Disable "Do not show my picture" on Lync client

Hi all, is it possible to disable the "Do not show my picture" on Lync client ?
I want to stop that an user can disable photo.

Thanks a lot

February 3rd, 2011 12:11pm

I haven't tested this yet, but have you played with creating a CsClientPolicy and applying it to the users. 

http://www.shudnow.net/2010/10/28/lync-2010-client-policies/

http://technet.microsoft.com/en-us/library/gg398300.aspx

The DisplayPhoto attribute has a number of options:

Determines whether or not photos (of both the user and his or her contacts) will be displayed in Lync 2010. Valid settings are:

NoPhoto - Photos are not displayed in Lync 2010.

PhotosFromADOnly - Only photos that have been published in Active Directory Domain Services (AD DS) can be displayed.

AllPhotos - Either Active Directory photos or custom photos can be displayed.

The default value is AllPhotos.

Free Windows Admin Tool Kit Click here and download it now
February 3rd, 2011 7:41pm

Hi Mark, yes CsClientPolicy work well, and I just set PhotosFromADOnly. But any user still have the choice "do not show my picture" in the Lync client option.

I need that user pictore is always on.

Thanks

Regards

Pietro

February 4th, 2011 9:10am

Hi, Pietro, that is an expected behavior and no solution at present.
Free Windows Admin Tool Kit Click here and download it now
February 10th, 2011 12:45pm

Do you have any idea when a resolution for this will be available? As a business we have invested a great deal in our Lync infrastructure and not to be able to perform something as basic as this is quite disappointing.
March 4th, 2011 1:20pm

Hi,

Please visit the below link to see the various paid support options that are available to better meet your needs. http://support.microsoft.com/default.aspx?id=fh;en-us;offerprophone

Free Windows Admin Tool Kit Click here and download it now
March 7th, 2011 5:42am

There are many of us who administer Lync that need to disable "Do not show my picture" and force users to use the Corporate Photo. Let me know when someone beats this... Thanks!

March 22nd, 2011 8:03pm

There are many of us who administer Lync that need to disable "Do not show my picture" and force users to use the Corporate Photo. Let me know when someone beats this... Thanks!


Free Windows Admin Tool Kit Click here and download it now
March 23rd, 2011 11:58pm

looking for the same thing :( no solutions yet
March 31st, 2011 1:51pm

I'm still annoyed that nothing seems to have been done regarding this yet. Can anyone from Microsoft comment on when we can expect this functionality?
Free Windows Admin Tool Kit Click here and download it now
April 12th, 2011 2:29pm

I will also chime in with needing to FORCE the picture in AD.  I have the clientpolicy setup to show the AD picture, but I have users disabling the photo; I need that option disabled.
April 13th, 2011 4:20pm

Agreed. Something we are looking for also. There should be a policy argument to prevent users from disabling the picture option. Please, please, please MS, can something be done about this oversight?
Free Windows Admin Tool Kit Click here and download it now
May 3rd, 2011 2:05am

Yes, a policy is needed to prevent users disabling their picture. We're just rolling Lync out and this is going to be a problem.
June 1st, 2011 9:02pm

This needs a solution. I figure there is a setting somewhere central that controls each user's picture preference, because it persists even if you have multiple PCs, but I can't find a cmdlet that modifies these properties.
Free Windows Admin Tool Kit Click here and download it now
June 15th, 2011 8:27pm

Just in case someone from the Lync product group see's this allow me to also add that is absolutely becoming a requirement in our business, especially after inversting in Lync and setting up a process to add pictures to AD, having users able to disable the picture completely eliminates a lot of Lync's value.
June 23rd, 2011 7:34pm

Just in case someone from the Lync product group see's this allow me to also add that is absolutely becoming a requirement in our business, especially after inversting in Lync and setting up a process to add pictures to AD, having users able to disable the picture completely eliminates a lot of Lync's value.

+1  (you know - in the Google sense)  :-)
Free Windows Admin Tool Kit Click here and download it now
July 4th, 2011 5:56pm

For those of you who strongly have a business case for this feature, how many users are affected in your respective organizations?

 

July 5th, 2011 10:22am

150 ?
Free Windows Admin Tool Kit Click here and download it now
July 5th, 2011 10:27am

For Lee;

Potential of 200+ users at this time. More depending on the adoption rate.

larry

July 5th, 2011 6:10pm

200+

As we have offices all throughout Canada, it is considered important that employees remain connected through IM and SharePoint, and the ability to see pictures of all employees, especially remote ones, enables those working together to put a face to the name.

 

Free Windows Admin Tool Kit Click here and download it now
July 6th, 2011 6:29pm

200+ right now. 
July 6th, 2011 7:03pm

I would also really like to see a fix for this as we are getting the same issues as everybody else here - 2000 users.

Thanks,

John

Free Windows Admin Tool Kit Click here and download it now
July 6th, 2011 11:39pm

3500+  We are rolling out globally, and replacing SPARC.  We need to force the use of the internal badge pictures as part of corporate policy.

 

d

July 8th, 2011 9:31pm

For those of you who strongly have a business case for this feature, how many users are affected in your respective organizations?

Free Windows Admin Tool Kit Click here and download it now
July 11th, 2011 5:52am

hmmm...  yes i see what u mean...  i too am looking

July 12th, 2011 6:08pm

hmmm...  yes i see what u mean...  i too am looking

Free Windows Admin Tool Kit Click here and download it now
July 12th, 2011 6:08pm

hmmm...  yes i see what u mean...  i too am looking

July 12th, 2011 6:08pm

hmmm...  yes i see what u mean...  i too am looking

Free Windows Admin Tool Kit Click here and download it now
July 12th, 2011 6:08pm

hmmm...  yes i see what u mean...  i too am looking

July 12th, 2011 6:08pm

Well, i am being escalated to Lync Engineering.  I will post findings....
  • Proposed as answer by Donia Strand Friday, July 15, 2011 11:17 PM
Free Windows Admin Tool Kit Click here and download it now
July 12th, 2011 6:36pm

Well, i am being escalated to Lync Engineering.  I will post findings....
  • Proposed as answer by Donia Strand Friday, July 15, 2011 11:17 PM
July 12th, 2011 6:36pm

Well, i am being escalated to Lync Engineering.  I will post findings....
  • Proposed as answer by Donia Strand Friday, July 15, 2011 11:17 PM
Free Windows Admin Tool Kit Click here and download it now
July 12th, 2011 6:36pm

Well, i am being escalated to Lync Engineering.  I will post findings....
  • Proposed as answer by Donia Strand Friday, July 15, 2011 11:17 PM
July 12th, 2011 6:36pm

Well, i am being escalated to Lync Engineering.  I will post findings....
  • Proposed as answer by Donia Strand Friday, July 15, 2011 11:17 PM
Free Windows Admin Tool Kit Click here and download it now
July 12th, 2011 6:36pm

has anyone had any success with this method?

 

http://iconraja.wordpress.com/2010/12/20/forcing-active-directory-photos-with-lync-2010/

 

seems like it would work, just a bit drawn out.

July 12th, 2011 8:57pm

This doesn't stop users from disabling the photo once it is forced down from AD :)

That is the setting that we all need--users can't select "No Photo" on their Lync client--we need a policy to disable that.

We've rolled out to trial users and as soon as they discover this setting, half of them select no Photo--so we have blank spaces where photos should be in Lync.


Free Windows Admin Tool Kit Click here and download it now
July 12th, 2011 9:04pm

hmmm...  yes i see what u mean...  i too am looking

July 12th, 2011 9:08pm

It removes the option of the user choosing his/her own picture, but it does NOT remove the option of them selecting "Do not show my picture".   
Free Windows Admin Tool Kit Click here and download it now
July 12th, 2011 9:11pm

Well, i am being escalated to Lync Engineering.  I will post findings....
July 12th, 2011 9:36pm

Not sure why they closed this ticket with an "this is expected behaviour" when this is such an issue affecting so many Lync implementers. Dennis, please do let us know how you get on with Lync engineering. This seems to me to be a huge oversight that could easily fixed by Microsoft.
Free Windows Admin Tool Kit Click here and download it now
July 16th, 2011 2:19am

unmark this as an answer plz. :)
July 17th, 2011 3:38pm

So far i am in a holding pattern...  the MS Product Manager stated.... "I contacted one of our Lync engineers to research your question.  He has also reached out to the Product Group for input, but his contact is on vacation until Aug 1<sup>st</sup>.  "

 

 will keep you updated....

Free Windows Admin Tool Kit Click here and download it now
July 18th, 2011 7:44pm

Yes, our company doesn't allow users to do any kind of modification to their SharePoint photos, nor to choose NOT to display them: Why does Lync allow users to choose to not display their photo in an end-user setting that administrators can't modify? Sloppy.


August 4th, 2011 6:06pm

Yes, our company doesn't allow users to do any kind of modification to their SharePoint photos, nor to choose NOT to display them: Why does Lync allow users to choose to not display their photo in an end-user setting that administrators can't modify? Sloppy.


Free Windows Admin Tool Kit Click here and download it now
August 4th, 2011 6:06pm

Yes, our company doesn't allow users to do any kind of modification to their SharePoint photos, nor to choose NOT to display them: Why does Lync allow users to choose to not display their photo in an end-user setting that administrators can't modify? Sloppy.


August 4th, 2011 6:06pm

Yes, our company doesn't allow users to do any kind of modification to their SharePoint photos, nor to choose NOT to display them: Why does Lync allow users to choose to not display their photo in an end-user setting that administrators can't modify? Sloppy.


Free Windows Admin Tool Kit Click here and download it now
August 4th, 2011 6:06pm

Yes, our company doesn't allow users to do any kind of modification to their SharePoint photos, nor to choose NOT to display them: Why does Lync allow users to choose to not display their photo in an end-user setting that administrators can't modify? Sloppy.


August 4th, 2011 6:06pm

I'm still looking for a way to do this. This a SECURITY issue in my organization. We have many temps coming in and out, and we require our users to be able to recognize a new temp by their Lync picture! The ability to hide the picture, while modest, is a security problem!!! 

I can't choose to hide the photo on my ID card. This is the same type of issue here.

Oh, and for Desmond Lee, we have about 1800 users affected.

Free Windows Admin Tool Kit Click here and download it now
August 4th, 2011 9:00pm

Yes, our company doesn't allow users to do any kind of modification to their SharePoint photos, nor to choose NOT to display them: Why does Lync allow users to choose to not display their photo in an end-user setting that administrators can't modify? Sloppy.


August 4th, 2011 9:06pm

This certainly isn't a perfect fix - but I've figured out that you can use the dbimpexp tool to export a clients configuration to an xml file, replace the "FALSE" setting on the photo parameter with a "TRUE", and re-import the configuration again.

 

Next time the user logs in, their photo is displayed again. Our users soon got tired of hiding it every day.

 

Hopefully Microsoft sees fit to give us a GPO option to fix this in Wave 15.

  • Proposed as answer by David EA Monday, August 08, 2011 6:57 PM
Free Windows Admin Tool Kit Click here and download it now
August 8th, 2011 6:57pm

This certainly isn't a perfect fix - but I've figured out that you can use the dbimpexp tool to export a clients configuration to an xml file, replace the "FALSE" setting on the photo parameter with a "TRUE", and re-import the configuration again.

 

Next time the user logs in, their photo is displayed again. Our users soon got tired of hiding it every day.

 

Hopefully Microsoft sees fit to give us a GPO option to fix this in Wave 15.

  • Proposed as answer by David EA Monday, August 08, 2011 6:57 PM
August 8th, 2011 6:57pm

This certainly isn't a perfect fix - but I've figured out that you can use the dbimpexp tool to export a clients configuration to an xml file, replace the "FALSE" setting on the photo parameter with a "TRUE", and re-import the configuration again.

 

Next time the user logs in, their photo is displayed again. Our users soon got tired of hiding it every day.

 

Hopefully Microsoft sees fit to give us a GPO option to fix this in Wave 15.

  • Proposed as answer by David EA Monday, August 08, 2011 6:57 PM
Free Windows Admin Tool Kit Click here and download it now
August 8th, 2011 6:57pm

This certainly isn't a perfect fix - but I've figured out that you can use the dbimpexp tool to export a clients configuration to an xml file, replace the "FALSE" setting on the photo parameter with a "TRUE", and re-import the configuration again.

 

Next time the user logs in, their photo is displayed again. Our users soon got tired of hiding it every day.

 

Hopefully Microsoft sees fit to give us a GPO option to fix this in Wave 15.

  • Proposed as answer by David EA Monday, August 08, 2011 6:57 PM
August 8th, 2011 6:57pm

This certainly isn't a perfect fix - but I've figured out that you can use the dbimpexp tool to export a clients configuration to an xml file, replace the "FALSE" setting on the photo parameter with a "TRUE", and re-import the configuration again.

 

Next time the user logs in, their photo is displayed again. Our users soon got tired of hiding it every day.

 

Hopefully Microsoft sees fit to give us a GPO option to fix this in Wave 15.

  • Proposed as answer by David EA Monday, August 08, 2011 6:57 PM
Free Windows Admin Tool Kit Click here and download it now
August 8th, 2011 6:57pm

This certainly isn't a perfect fix - but I've figured out that you can use the dbimpexp tool to export a clients configuration to an xml file, replace the "FALSE" setting on the photo parameter with a "TRUE", and re-import the configuration again.

 

Next time the user logs in, their photo is displayed again. Our users soon got tired of hiding it every day.

 

Hopefully Microsoft sees fit to give us a GPO option to fix this in Wave 15.

August 8th, 2011 9:57pm

a groovie solution/workaround :)
Free Windows Admin Tool Kit Click here and download it now
August 8th, 2011 9:58pm

Can you post the script you created for dbimpexp?

Right now I'm thinking the solution is to run dbimpexp and export the entire database, then find/replace "<displayADPhoto>false</displayADPhoto>" and re-import?

August 11th, 2011 4:47pm

This certainly isn't a perfect fix - but I've figured out that you can use the dbimpexp tool to export a clients configuration to an xml file, replace the "FALSE" setting on the photo parameter with a "TRUE", and re-import the configuration again.

 

Next time the user logs in, their photo is displayed again. Our users soon got tired of hiding it every day.

 

Hopefully Microsoft sees fit to give us a GPO option to fix this in Wave 15.


Indeed. Great workaround. I've written the following PowerShell script for modifying the XML, because I wanted to update the Version and LastPubTime, like happens when you modify this setting through Lync.

If (Test-Path 'C:\scripts\Export.xml') { Remove-Item 'C:\scripts\Export.xml' }
If (Test-Path 'C:\scripts\Import.xml') { Remove-Item 'C:\scripts\Import.xml' }

"Exporting users..."
$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/hrxmlfile:c:\scripts\Export.xml /sqlserver:sqlserver /restype:user")
$p.WaitForExit()

"Loading xml"
$d = [xml] (Get-Content C:\scripts\Export.xml)

"Processing..."
$changes = 0
foreach ($hr in $d.HomedResources.HomedResource)
{
  foreach ($c in $hr.Containers.Container)
  {
    foreach ($p in $c.Publication)
    {
      if ($p.CategoryName -eq 'contactCard' -and $p.InstanceNum -eq 6 -and $p.Data.contactCard.displayADPhoto -eq 'false')
      {
		$hr.UserAtHost
        $p.Data.contactCard.displayADPhoto = 'true'
        $p.Version = (([int] $p.Version) + 1).ToString()
        $p.PrevPubTime = $p.LastPubTime
        $p.LastPubTime = (Get-Date -Format s).ToString()
        
        $changes++
      }
    }
  }
}

"Changes: $changes"
if ($changes -ne 0)
{
  "Saving xml"
  $d.Save("C:\scripts\Import.xml")

  "Importing users..."
  $p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/import /hrxmlfile:c:\scripts\Import.xml /sqlserver:sqlserver /restype:user")
  $p.WaitForExit()
}

"Done"

Create a C:\Scripts directory and or replace the C:\scripts references. Also change the sqlserver name when using EE, or remove the /sqlserver parameter when using SE
Free Windows Admin Tool Kit Click here and download it now
August 14th, 2011 9:47pm

Gerard, if it isn't terribly complicated, could you explain how to execute this code block?

Pretend I have absolutely no idea how to even begin using scripts. :)

Thanks!

kyle

August 15th, 2011 6:10pm

Gerard, if it isn't terribly complicated, could you explain how to execute this code block?

Pretend I have absolutely no idea how to even begin using scripts. :)

Thanks!

kyle

The easiest way is to create a folder C:\scripts, then Copy/Paste it to Notepad, and then modify the sqlserver name (or remove the attribute for SE).

You can then either copy it to the clipboard and paste it in a PowerShell window, or you can save it as c:\scripts\DisplayADPhoto.ps1 and then in PowerShell:

c:
cd \scripts
./DisplayADPhoto.ps1

If this last command doesn't work, you may have to run this command to enable local execution of unsigned scripts:

Set-ExecutionPolicy RemoteSigned
Free Windows Admin Tool Kit Click here and download it now
August 18th, 2011 4:11pm

Thanks, this worked for me!
August 18th, 2011 6:58pm

This has worked for me also...  Do you know if it runs while a user is logged in will it display their picture or do they need to close and reopen to take effect?

 

on side note, MS Developers have replied to the escalation i raised, and stated they do not have the option, nor do they have it in their immediate plans to add this feature.

Free Windows Admin Tool Kit Click here and download it now
August 19th, 2011 4:26pm

When I ran it the pictures showed up for users who didn't have their picture enabled in other people's contact lists, but their own picture didn't show up until they logged out and back in.
August 19th, 2011 5:09pm

One more thing that's worth mentioning is that you cannot call the script directly in a scheduled task.

If you want to run this as a scheduled task you will need to run it as:

powershell.exe -command "& 'c:\scripts\DisplayADPhoto.ps1'"

 

Free Windows Admin Tool Kit Click here and download it now
August 22nd, 2011 4:59pm

What's with the & ?

powershell -command c:\scripts\DisplayAdPhoto.ps1 works just fine....

August 22nd, 2011 5:03pm

To tell you the truth I'm not sure... I had never run a powershell script as a scheduled task and when I searched for how to do it the answer I found used this syntax. If it works without the & then I would say that is probably the right way.
Free Windows Admin Tool Kit Click here and download it now
August 22nd, 2011 5:05pm

After some testing, the users own picture will show up without logging off.  took about 2 hours, i do not know the refresh rate, so cannot say exactly.
August 22nd, 2011 6:33pm

Hello,

our company would also highly appreciate a fix for this. we do not want users to be able to disable the foto.

br

Free Windows Admin Tool Kit Click here and download it now
September 22nd, 2011 6:16pm

Hello,

i modified the script so it only uploads the users that have been changed:

foreach ($hr in $d.HomedResources.HomedResource)
{
  $found = 0
  foreach ($c in $hr.Containers.Container)
  {
    foreach ($p in $c.Publication)
    {
      if ($p.CategoryName -eq 'contactCard' -and $p.InstanceNum -eq 6 -and $p.Data.contactCard.displayADPhoto -eq 'false')
      {
		$hr.UserAtHost
        $p.Data.contactCard.displayADPhoto = 'true'
        $p.Version = (([int] $p.Version) + 1).ToString()
        $p.PrevPubTime = $p.LastPubTime
        $p.LastPubTime = (Get-Date -Format s).ToString()
		$found = 1
        $changes++
      }
    }
  }
  if ($found -eq 0)
  {
	[Void]$d.HomedResources.RemoveChild($hr)
  }
}

thanks and br

September 23rd, 2011 10:48am

Hello,

i modified the script so it only uploads the users that have been changed:

foreach ($hr in $d.HomedResources.HomedResource)
{
  $found = 0
  foreach ($c in $hr.Containers.Container)
  {
    foreach ($p in $c.Publication)
    {
      if ($p.CategoryName -eq 'contactCard' -and $p.InstanceNum -eq 6 -and $p.Data.contactCard.displayADPhoto -eq 'false')
      {
		$hr.UserAtHost
        $p.Data.contactCard.displayADPhoto = 'true'
        $p.Version = (([int] $p.Version) + 1).ToString()
        $p.PrevPubTime = $p.LastPubTime
        $p.LastPubTime = (Get-Date -Format s).ToString()
		$found = 1
        $changes++
      }
    }
  }
  if ($found -eq 0)
  {
	[Void]$d.HomedResources.RemoveChild($hr)
  }
}

thanks and br

Free Windows Admin Tool Kit Click here and download it now
September 23rd, 2011 10:48am

Hello,

i modified the script so it only uploads the users that have been changed:

foreach ($hr in $d.HomedResources.HomedResource)
{
  $found = 0
  foreach ($c in $hr.Containers.Container)
  {
    foreach ($p in $c.Publication)
    {
      if ($p.CategoryName -eq 'contactCard' -and $p.InstanceNum -eq 6 -and $p.Data.contactCard.displayADPhoto -eq 'false')
      {
		$hr.UserAtHost
        $p.Data.contactCard.displayADPhoto = 'true'
        $p.Version = (([int] $p.Version) + 1).ToString()
        $p.PrevPubTime = $p.LastPubTime
        $p.LastPubTime = (Get-Date -Format s).ToString()
		$found = 1
        $changes++
      }
    }
  }
  if ($found -eq 0)
  {
	[Void]$d.HomedResources.RemoveChild($hr)
  }
}

thanks and br

September 23rd, 2011 10:48am

Hello,

i modified the script so it only uploads the users that have been changed:

foreach ($hr in $d.HomedResources.HomedResource)
{
  $found = 0
  foreach ($c in $hr.Containers.Container)
  {
    foreach ($p in $c.Publication)
    {
      if ($p.CategoryName -eq 'contactCard' -and $p.InstanceNum -eq 6 -and $p.Data.contactCard.displayADPhoto -eq 'false')
      {
		$hr.UserAtHost
        $p.Data.contactCard.displayADPhoto = 'true'
        $p.Version = (([int] $p.Version) + 1).ToString()
        $p.PrevPubTime = $p.LastPubTime
        $p.LastPubTime = (Get-Date -Format s).ToString()
		$found = 1
        $changes++
      }
    }
  }
  if ($found -eq 0)
  {
	[Void]$d.HomedResources.RemoveChild($hr)
  }
}

thanks and br

Free Windows Admin Tool Kit Click here and download it now
September 23rd, 2011 10:48am

Hello,

i modified the script so it only uploads the users that have been changed:

foreach ($hr in $d.HomedResources.HomedResource)
{
  $found = 0
  foreach ($c in $hr.Containers.Container)
  {
    foreach ($p in $c.Publication)
    {
      if ($p.CategoryName -eq 'contactCard' -and $p.InstanceNum -eq 6 -and $p.Data.contactCard.displayADPhoto -eq 'false')
      {
		$hr.UserAtHost
        $p.Data.contactCard.displayADPhoto = 'true'
        $p.Version = (([int] $p.Version) + 1).ToString()
        $p.PrevPubTime = $p.LastPubTime
        $p.LastPubTime = (Get-Date -Format s).ToString()
		$found = 1
        $changes++
      }
    }
  }
  if ($found -eq 0)
  {
	[Void]$d.HomedResources.RemoveChild($hr)
  }
}

thanks and br

September 23rd, 2011 10:48am

Hello,

i modified the script so it only uploads the users that have been changed:

foreach ($hr in $d.HomedResources.HomedResource)
{
  $found = 0
  foreach ($c in $hr.Containers.Container)
  {
    foreach ($p in $c.Publication)
    {
      if ($p.CategoryName -eq 'contactCard' -and $p.InstanceNum -eq 6 -and $p.Data.contactCard.displayADPhoto -eq 'false')
      {
		$hr.UserAtHost
        $p.Data.contactCard.displayADPhoto = 'true'
        $p.Version = (([int] $p.Version) + 1).ToString()
        $p.PrevPubTime = $p.LastPubTime
        $p.LastPubTime = (Get-Date -Format s).ToString()
		$found = 1
        $changes++
      }
    }
  }
  if ($found -eq 0)
  {
	[Void]$d.HomedResources.RemoveChild($hr)
  }
}

thanks and br

Free Windows Admin Tool Kit Click here and download it now
September 23rd, 2011 1:48pm

Hi,

       Even we are looking for a solution on this.

       More then 7000 users will be affected.

       Hope Mircrosoft provides a solution through GPO.

       Eagerly waiting.

 

Thanks,

Amit.

October 4th, 2011 7:34am

Same here.  Not being able to force user photos completed negates all of the effort to upload photos in the first place.  Not to mention this has become an HR requirement. 
Free Windows Admin Tool Kit Click here and download it now
October 10th, 2011 8:22pm

Hi All,

My recommendation for all that have deemed this a business requirement is to escalate this feature request through your Microsoft account managers so the UC product group receives your feedback.

October 11th, 2011 2:46pm

Hello! I am also waiting for the option to disable "do not show my picture" in lync client. 600 users here.
Free Windows Admin Tool Kit Click here and download it now
October 17th, 2011 11:15am

This script along with Robert Rostek's modification to only upload changes is an excellent workaround until MS comes to their senses.
October 26th, 2011 2:03am

I have tried the scripts listed in this thread and I continue to get the following:

 

Get-Content : Cannot find path 'C:\Scripts\Export.xml' because it does not exist.

At C:\scripts\ADPhoto.ps1:9 char:24

+ $d = [xml] (Get-Content <<<<  C:\Scripts\Export.xml)

    + CategoryInfo          : ObjectNotFound: (C:\Scripts\Export.xml:String) [Get-Content], ItemNotFoundException

    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand

 

Processing...

Changes: 0

Done

 

It doesn't seem to be producing the XML ?

Free Windows Admin Tool Kit Click here and download it now
December 20th, 2011 5:31pm

Make sure you are running on the Lync server and that the user executing the script has write permissions to C:\Scripts (or move the script and edit it for the directory you want it to run from).
December 20th, 2011 7:06pm

Yep I certainly have permissions to write to the directory.

For the /sqlserver:sqlserver I have changed this to read:

/sqlserver:localhost ?

Is this correct?

Free Windows Admin Tool Kit Click here and download it now
December 21st, 2011 7:13am

Try this script, I've edited it to make it a little clearer what areas need to be changed.

# script to re-enable AD photos for users that have disabled them

# DNS Name of SQL Server - Leave Blank for SQL Server Express
$sqlserver = ''	

# This is the directory where exports will be placed temporarily - you must have write access to this directory
$exportdir = 'C:\Lync-Scripts'


########## DO NOT EDIT BELOW THIS LINE ##########

"Checking for Export Directory"
If (-not (Test-Path "$exportdir" -pathType container))
{
	"ERROR: Your Export Directory doesn't exist!"
	Exit
}

"Cleaning up old files..."
If (Test-Path "$exportdir\Export-Pictures.xml") { Remove-Item "$exportdir\Export-Pictures.xml" }
If (Test-Path "$exportdir\Import-Pictures.xml") { Remove-Item "$exportdir\Import-Pictures.xml" }

# check to see if we need to have an sqlserver argument to DBImpExp
If ($sqlserver -ne "")
{
	"Query will be run against SQL server ""$sqlserver"""
	$sqlserver = "/sqlserver:$sqlserver"
}

"Exporting users..."
$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/hrxmlfile:""$exportdir\Export-Pictures.xml"" /restype:user $sqlserver")
$p.WaitForExit()

# check that XML was exported
If (-not (Test-Path "$exportdir\Export-Pictures.xml" -pathType leaf))
{
	"ERROR: Verify that $exportdir is writable!"
	Exit
}

"Loading XML"
$d = [xml] (Get-Content "$exportdir\Export-Pictures.xml")

"Processing..."
$changes = 0
foreach ($hr in $d.HomedResources.HomedResource)
{
	$found = 0
	foreach ($c in $hr.Containers.Container)
	{
		foreach ($p in $c.Publication)
		{
			If ($p.CategoryName -eq 'contactCard' -and $p.InstanceNum -eq 6 -and $p.Data.contactCard.displayADPhoto -eq 'false')
			{
				$hr.UserAtHost
				$p.Data.contactCard.displayADPhoto = 'true'
				$p.Version = (([int] $p.Version) + 1).ToString()
				$p.PrevPubTime = $p.LastPubTime
				$p.LastPubTime = (Get-Date -Format s).ToString()
				$found = 1
				$changes++
			}
		}
	}
	If ($found -eq 0) { [Void]$d.HomedResources.RemoveChild($hr) }
}

"Changes: $changes"
If ($changes -ne 0)
{
	"Saving XML..."
	$d.Save("$exportdir\Import-Pictures.xml")

	"Importing users..."
	$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/import /hrxmlfile:""$exportdir\Import-Pictures.xml"" /restype:user $sqlserver")
	$p.WaitForExit()
}

"Finished import, cleaning up..."
If (Test-Path "$exportdir\Export-Pictures.xml") { Remove-Item "$exportdir\Export-Pictures.xml" }
If (Test-Path "$exportdir\Import-Pictures.xml") { Remove-Item "$exportdir\Import-Pictures.xml" }

"Done"


Also, please note that the default installation of Lync uses SQL Server Express and you don't need to provide the SQL server.

  • Proposed as answer by Shannon Brooks Wednesday, February 15, 2012 7:57 PM
December 21st, 2011 8:40pm

Try this script, I've edited it to make it a little clearer what areas need to be changed.

# script to re-enable AD photos for users that have disabled them

# DNS Name of SQL Server - Leave Blank for SQL Server Express
$sqlserver = ''	

# This is the directory where exports will be placed temporarily - you must have write access to this directory
$exportdir = 'C:\Lync-Scripts'


########## DO NOT EDIT BELOW THIS LINE ##########

"Checking for Export Directory"
If (-not (Test-Path "$exportdir" -pathType container))
{
	"ERROR: Your Export Directory doesn't exist!"
	Exit
}

"Cleaning up old files..."
If (Test-Path "$exportdir\Export-Pictures.xml") { Remove-Item "$exportdir\Export-Pictures.xml" }
If (Test-Path "$exportdir\Import-Pictures.xml") { Remove-Item "$exportdir\Import-Pictures.xml" }

# check to see if we need to have an sqlserver argument to DBImpExp
If ($sqlserver -ne "")
{
	"Query will be run against SQL server ""$sqlserver"""
	$sqlserver = "/sqlserver:$sqlserver"
}

"Exporting users..."
$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/hrxmlfile:""$exportdir\Export-Pictures.xml"" /restype:user $sqlserver")
$p.WaitForExit()

# check that XML was exported
If (-not (Test-Path "$exportdir\Export-Pictures.xml" -pathType leaf))
{
	"ERROR: Verify that $exportdir is writable!"
	Exit
}

"Loading XML"
$d = [xml] (Get-Content "$exportdir\Export-Pictures.xml")

"Processing..."
$changes = 0
foreach ($hr in $d.HomedResources.HomedResource)
{
	$found = 0
	foreach ($c in $hr.Containers.Container)
	{
		foreach ($p in $c.Publication)
		{
			If ($p.CategoryName -eq 'contactCard' -and $p.InstanceNum -eq 6 -and $p.Data.contactCard.displayADPhoto -eq 'false')
			{
				$hr.UserAtHost
				$p.Data.contactCard.displayADPhoto = 'true'
				$p.Version = (([int] $p.Version) + 1).ToString()
				$p.PrevPubTime = $p.LastPubTime
				$p.LastPubTime = (Get-Date -Format s).ToString()
				$found = 1
				$changes++
			}
		}
	}
	If ($found -eq 0) { [Void]$d.HomedResources.RemoveChild($hr) }
}

"Changes: $changes"
If ($changes -ne 0)
{
	"Saving XML..."
	$d.Save("$exportdir\Import-Pictures.xml")

	"Importing users..."
	$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/import /hrxmlfile:""$exportdir\Import-Pictures.xml"" /restype:user $sqlserver")
	$p.WaitForExit()
}

"Finished import, cleaning up..."
If (Test-Path "$exportdir\Export-Pictures.xml") { Remove-Item "$exportdir\Export-Pictures.xml" }
If (Test-Path "$exportdir\Import-Pictures.xml") { Remove-Item "$exportdir\Import-Pictures.xml" }

"Done"


Also, please note that the default installation of Lync uses SQL Server Express and you don't need to provide the SQL server.

  • Proposed as answer by Shannon Brooks Wednesday, February 15, 2012 7:57 PM
Free Windows Admin Tool Kit Click here and download it now
December 21st, 2011 8:40pm

Try this script, I've edited it to make it a little clearer what areas need to be changed.

# script to re-enable AD photos for users that have disabled them

# DNS Name of SQL Server - Leave Blank for SQL Server Express
$sqlserver = ''	

# This is the directory where exports will be placed temporarily - you must have write access to this directory
$exportdir = 'C:\Lync-Scripts'


########## DO NOT EDIT BELOW THIS LINE ##########

"Checking for Export Directory"
If (-not (Test-Path "$exportdir" -pathType container))
{
	"ERROR: Your Export Directory doesn't exist!"
	Exit
}

"Cleaning up old files..."
If (Test-Path "$exportdir\Export-Pictures.xml") { Remove-Item "$exportdir\Export-Pictures.xml" }
If (Test-Path "$exportdir\Import-Pictures.xml") { Remove-Item "$exportdir\Import-Pictures.xml" }

# check to see if we need to have an sqlserver argument to DBImpExp
If ($sqlserver -ne "")
{
	"Query will be run against SQL server ""$sqlserver"""
	$sqlserver = "/sqlserver:$sqlserver"
}

"Exporting users..."
$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/hrxmlfile:""$exportdir\Export-Pictures.xml"" /restype:user $sqlserver")
$p.WaitForExit()

# check that XML was exported
If (-not (Test-Path "$exportdir\Export-Pictures.xml" -pathType leaf))
{
	"ERROR: Verify that $exportdir is writable!"
	Exit
}

"Loading XML"
$d = [xml] (Get-Content "$exportdir\Export-Pictures.xml")

"Processing..."
$changes = 0
foreach ($hr in $d.HomedResources.HomedResource)
{
	$found = 0
	foreach ($c in $hr.Containers.Container)
	{
		foreach ($p in $c.Publication)
		{
			If ($p.CategoryName -eq 'contactCard' -and $p.InstanceNum -eq 6 -and $p.Data.contactCard.displayADPhoto -eq 'false')
			{
				$hr.UserAtHost
				$p.Data.contactCard.displayADPhoto = 'true'
				$p.Version = (([int] $p.Version) + 1).ToString()
				$p.PrevPubTime = $p.LastPubTime
				$p.LastPubTime = (Get-Date -Format s).ToString()
				$found = 1
				$changes++
			}
		}
	}
	If ($found -eq 0) { [Void]$d.HomedResources.RemoveChild($hr) }
}

"Changes: $changes"
If ($changes -ne 0)
{
	"Saving XML..."
	$d.Save("$exportdir\Import-Pictures.xml")

	"Importing users..."
	$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/import /hrxmlfile:""$exportdir\Import-Pictures.xml"" /restype:user $sqlserver")
	$p.WaitForExit()
}

"Finished import, cleaning up..."
If (Test-Path "$exportdir\Export-Pictures.xml") { Remove-Item "$exportdir\Export-Pictures.xml" }
If (Test-Path "$exportdir\Import-Pictures.xml") { Remove-Item "$exportdir\Import-Pictures.xml" }

"Done"


Also, please note that the default installation of Lync uses SQL Server Express and you don't need to provide the SQL server.

  • Proposed as answer by Shannon Brooks Wednesday, February 15, 2012 7:57 PM
December 21st, 2011 8:40pm

Try this script, I've edited it to make it a little clearer what areas need to be changed.

# script to re-enable AD photos for users that have disabled them

# DNS Name of SQL Server - Leave Blank for SQL Server Express
$sqlserver = ''	

# This is the directory where exports will be placed temporarily - you must have write access to this directory
$exportdir = 'C:\Lync-Scripts'


########## DO NOT EDIT BELOW THIS LINE ##########

"Checking for Export Directory"
If (-not (Test-Path "$exportdir" -pathType container))
{
	"ERROR: Your Export Directory doesn't exist!"
	Exit
}

"Cleaning up old files..."
If (Test-Path "$exportdir\Export-Pictures.xml") { Remove-Item "$exportdir\Export-Pictures.xml" }
If (Test-Path "$exportdir\Import-Pictures.xml") { Remove-Item "$exportdir\Import-Pictures.xml" }

# check to see if we need to have an sqlserver argument to DBImpExp
If ($sqlserver -ne "")
{
	"Query will be run against SQL server ""$sqlserver"""
	$sqlserver = "/sqlserver:$sqlserver"
}

"Exporting users..."
$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/hrxmlfile:""$exportdir\Export-Pictures.xml"" /restype:user $sqlserver")
$p.WaitForExit()

# check that XML was exported
If (-not (Test-Path "$exportdir\Export-Pictures.xml" -pathType leaf))
{
	"ERROR: Verify that $exportdir is writable!"
	Exit
}

"Loading XML"
$d = [xml] (Get-Content "$exportdir\Export-Pictures.xml")

"Processing..."
$changes = 0
foreach ($hr in $d.HomedResources.HomedResource)
{
	$found = 0
	foreach ($c in $hr.Containers.Container)
	{
		foreach ($p in $c.Publication)
		{
			If ($p.CategoryName -eq 'contactCard' -and $p.InstanceNum -eq 6 -and $p.Data.contactCard.displayADPhoto -eq 'false')
			{
				$hr.UserAtHost
				$p.Data.contactCard.displayADPhoto = 'true'
				$p.Version = (([int] $p.Version) + 1).ToString()
				$p.PrevPubTime = $p.LastPubTime
				$p.LastPubTime = (Get-Date -Format s).ToString()
				$found = 1
				$changes++
			}
		}
	}
	If ($found -eq 0) { [Void]$d.HomedResources.RemoveChild($hr) }
}

"Changes: $changes"
If ($changes -ne 0)
{
	"Saving XML..."
	$d.Save("$exportdir\Import-Pictures.xml")

	"Importing users..."
	$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/import /hrxmlfile:""$exportdir\Import-Pictures.xml"" /restype:user $sqlserver")
	$p.WaitForExit()
}

"Finished import, cleaning up..."
If (Test-Path "$exportdir\Export-Pictures.xml") { Remove-Item "$exportdir\Export-Pictures.xml" }
If (Test-Path "$exportdir\Import-Pictures.xml") { Remove-Item "$exportdir\Import-Pictures.xml" }

"Done"


Also, please note that the default installation of Lync uses SQL Server Express and you don't need to provide the SQL server.

  • Proposed as answer by Shannon Brooks Wednesday, February 15, 2012 7:57 PM
Free Windows Admin Tool Kit Click here and download it now
December 21st, 2011 8:40pm

Try this script, I've edited it to make it a little clearer what areas need to be changed.

# script to re-enable AD photos for users that have disabled them

# DNS Name of SQL Server - Leave Blank for SQL Server Express
$sqlserver = ''	

# This is the directory where exports will be placed temporarily - you must have write access to this directory
$exportdir = 'C:\Lync-Scripts'


########## DO NOT EDIT BELOW THIS LINE ##########

"Checking for Export Directory"
If (-not (Test-Path "$exportdir" -pathType container))
{
	"ERROR: Your Export Directory doesn't exist!"
	Exit
}

"Cleaning up old files..."
If (Test-Path "$exportdir\Export-Pictures.xml") { Remove-Item "$exportdir\Export-Pictures.xml" }
If (Test-Path "$exportdir\Import-Pictures.xml") { Remove-Item "$exportdir\Import-Pictures.xml" }

# check to see if we need to have an sqlserver argument to DBImpExp
If ($sqlserver -ne "")
{
	"Query will be run against SQL server ""$sqlserver"""
	$sqlserver = "/sqlserver:$sqlserver"
}

"Exporting users..."
$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/hrxmlfile:""$exportdir\Export-Pictures.xml"" /restype:user $sqlserver")
$p.WaitForExit()

# check that XML was exported
If (-not (Test-Path "$exportdir\Export-Pictures.xml" -pathType leaf))
{
	"ERROR: Verify that $exportdir is writable!"
	Exit
}

"Loading XML"
$d = [xml] (Get-Content "$exportdir\Export-Pictures.xml")

"Processing..."
$changes = 0
foreach ($hr in $d.HomedResources.HomedResource)
{
	$found = 0
	foreach ($c in $hr.Containers.Container)
	{
		foreach ($p in $c.Publication)
		{
			If ($p.CategoryName -eq 'contactCard' -and $p.InstanceNum -eq 6 -and $p.Data.contactCard.displayADPhoto -eq 'false')
			{
				$hr.UserAtHost
				$p.Data.contactCard.displayADPhoto = 'true'
				$p.Version = (([int] $p.Version) + 1).ToString()
				$p.PrevPubTime = $p.LastPubTime
				$p.LastPubTime = (Get-Date -Format s).ToString()
				$found = 1
				$changes++
			}
		}
	}
	If ($found -eq 0) { [Void]$d.HomedResources.RemoveChild($hr) }
}

"Changes: $changes"
If ($changes -ne 0)
{
	"Saving XML..."
	$d.Save("$exportdir\Import-Pictures.xml")

	"Importing users..."
	$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/import /hrxmlfile:""$exportdir\Import-Pictures.xml"" /restype:user $sqlserver")
	$p.WaitForExit()
}

"Finished import, cleaning up..."
If (Test-Path "$exportdir\Export-Pictures.xml") { Remove-Item "$exportdir\Export-Pictures.xml" }
If (Test-Path "$exportdir\Import-Pictures.xml") { Remove-Item "$exportdir\Import-Pictures.xml" }

"Done"


Also, please note that the default installation of Lync uses SQL Server Express and you don't need to provide the SQL server.

  • Proposed as answer by Shannon Brooks Wednesday, February 15, 2012 7:57 PM
December 21st, 2011 8:40pm

Try this script, I've edited it to make it a little clearer what areas need to be changed.

# script to re-enable AD photos for users that have disabled them

# DNS Name of SQL Server - Leave Blank for SQL Server Express
$sqlserver = ''	

# This is the directory where exports will be placed temporarily - you must have write access to this directory
$exportdir = 'C:\Lync-Scripts'


########## DO NOT EDIT BELOW THIS LINE ##########

"Checking for Export Directory"
If (-not (Test-Path "$exportdir" -pathType container))
{
	"ERROR: Your Export Directory doesn't exist!"
	Exit
}

"Cleaning up old files..."
If (Test-Path "$exportdir\Export-Pictures.xml") { Remove-Item "$exportdir\Export-Pictures.xml" }
If (Test-Path "$exportdir\Import-Pictures.xml") { Remove-Item "$exportdir\Import-Pictures.xml" }

# check to see if we need to have an sqlserver argument to DBImpExp
If ($sqlserver -ne "")
{
	"Query will be run against SQL server ""$sqlserver"""
	$sqlserver = "/sqlserver:$sqlserver"
}

"Exporting users..."
$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/hrxmlfile:""$exportdir\Export-Pictures.xml"" /restype:user $sqlserver")
$p.WaitForExit()

# check that XML was exported
If (-not (Test-Path "$exportdir\Export-Pictures.xml" -pathType leaf))
{
	"ERROR: Verify that $exportdir is writable!"
	Exit
}

"Loading XML"
$d = [xml] (Get-Content "$exportdir\Export-Pictures.xml")

"Processing..."
$changes = 0
foreach ($hr in $d.HomedResources.HomedResource)
{
	$found = 0
	foreach ($c in $hr.Containers.Container)
	{
		foreach ($p in $c.Publication)
		{
			If ($p.CategoryName -eq 'contactCard' -and $p.InstanceNum -eq 6 -and $p.Data.contactCard.displayADPhoto -eq 'false')
			{
				$hr.UserAtHost
				$p.Data.contactCard.displayADPhoto = 'true'
				$p.Version = (([int] $p.Version) + 1).ToString()
				$p.PrevPubTime = $p.LastPubTime
				$p.LastPubTime = (Get-Date -Format s).ToString()
				$found = 1
				$changes++
			}
		}
	}
	If ($found -eq 0) { [Void]$d.HomedResources.RemoveChild($hr) }
}

"Changes: $changes"
If ($changes -ne 0)
{
	"Saving XML..."
	$d.Save("$exportdir\Import-Pictures.xml")

	"Importing users..."
	$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/import /hrxmlfile:""$exportdir\Import-Pictures.xml"" /restype:user $sqlserver")
	$p.WaitForExit()
}

"Finished import, cleaning up..."
If (Test-Path "$exportdir\Export-Pictures.xml") { Remove-Item "$exportdir\Export-Pictures.xml" }
If (Test-Path "$exportdir\Import-Pictures.xml") { Remove-Item "$exportdir\Import-Pictures.xml" }

"Done"


Also, please note that the default installation of Lync uses SQL Server Express and you don't need to provide the SQL server.

Free Windows Admin Tool Kit Click here and download it now
December 21st, 2011 11:40pm

Worked perfectly Shannon.

Many Thanks!

December 22nd, 2011 2:22am

Add me to the list.  We have about 200 users and don't want them hiding their photos!  It's good for security and getting to know your co-workers.  We're about to migrate everyone from OC 2007 to Lync.
Free Windows Admin Tool Kit Click here and download it now
February 1st, 2012 11:31pm

I did have one user that threw off an error on this:

Property 'PrevPubTime' cannot be found on this object; make sure it exists and is settable.

Are all these settings in Active Directory?

Thanks for any help.

February 16th, 2012 7:59pm

Is it a new user that was just created? If you wait until the new address book is published I think that error will go away.
Free Windows Admin Tool Kit Click here and download it now
February 16th, 2012 8:05pm

Add me as well

1000+ users

Dave

April 13th, 2012 1:49pm

Add me as well

600+ users

Free Windows Admin Tool Kit Click here and download it now
April 17th, 2012 7:58pm

Hi Des,

Have you got any news on this, is it still worth posting?

Cheers

April 18th, 2012 1:07pm

I'll keep up with this thread until MS adds this feature, or the new version of Lync comes out (assuming it's included there).
Free Windows Admin Tool Kit Click here and download it now
April 18th, 2012 7:18pm

Great!

Thanks for the script. Is possible to add some logging functions - how many people was updated a who?

Thank you for your response
jcerny

April 19th, 2012 10:09am

Going to be about 100 users in another week.  Probably 250 in another month.  We need this as well.
Free Windows Admin Tool Kit Click here and download it now
April 24th, 2012 11:58pm

We have 900 users that this is affecting. Microsoft needs to put in an official fix for this. Lync isn't a a product used by the public - it's for corporate use ONLY. I don't understand why MS would roll out anything that allows the client to make changes that the administrator cannot control.
April 25th, 2012 5:48pm

We have about 150 users and would also like to make sure users don't have the ability to turn off the corporate photo.

Thanks,

Free Windows Admin Tool Kit Click here and download it now
April 30th, 2012 9:04pm

We are about to go live with close to 7000+ users, and the ability for users to turn off their photos is unacceptable.  Ben-Shun Zhu needs to correct his marking of this as being resolved.  There is a work-around, and his response is far from a solution!
May 1st, 2012 7:34pm

We have 210 users and also want to force pictures -- Thanks for the workaround but Microsoft needs to get on the ball and listen to it's customer base.    Fix it
Free Windows Admin Tool Kit Click here and download it now
May 7th, 2012 8:18pm

Shannon - we use Lync 2010 in Office 365 (hosted).  I assume it's not possible to apply your solution in this case since I don't technically have a Lync server?

Thanks,
lunchroom

May 8th, 2012 11:15pm

I haven't used Office 365 yet, but I would assume that unless you have access to the console you couldn't run the script. Do they provide any remote management tools with Office 365?
Free Windows Admin Tool Kit Click here and download it now
May 8th, 2012 11:19pm

looks like some basic powershell can be done with office365:
http://blog.insidelync.com/2011/09/handy-powershell-administration-script-for-office-365-2/

(i'm not 365 guru at all)

May 8th, 2012 11:26pm

I'm thinking that this probably won't work as we are using DBImpExp.exe to dump the XML from the database and then reinsert it.
Free Windows Admin Tool Kit Click here and download it now
May 9th, 2012 12:33am

That's what I was thinking as well.  Thanks for your input.
May 9th, 2012 12:37am

Same problem here.  300 users.  Everyone has an AD photo.. We need to be able to disable the "Do not show my Picture" option.
Free Windows Admin Tool Kit Click here and download it now
May 10th, 2012 10:00pm

The best approach to gain some traction with this feature request is to provide sufficient business justification (i.e. how would this feature help your business) to Microsoft Support as a premier customer (PSS).
May 14th, 2012 5:13pm

This issue has been around a long time.  It affecting 1100 users here.  It appears there are thousands and thousands of users who need to be able to disable users from selecting No Photo.  I will contact my Corp Rep as well.
Free Windows Admin Tool Kit Click here and download it now
May 30th, 2012 5:41pm

1500 Corporate/Office based Users. 6000 or so in non office locations, so we need to see their faces as we rarely come into contact with them day to day.

June 22nd, 2012 2:38pm

Same issue here, lots of users moving around, lots of users spread out over large geographical area in numerous offices, lots of users with the same name (Welsh names tend to all be the same or similar in certain areas with people having 4 or more given names before their surname and picking one of those to use with their surname)
Free Windows Admin Tool Kit Click here and download it now
June 22nd, 2012 2:42pm

When I run the script I get 4 lines for each user than has a change made, any ideas what causes this?

e.g. say matth@domain.co.uk changed his settings I would get

matth@domain.co.uk
matth@domain.co.uk
matth@domain.co.uk
matth@domain.co.uk
Changes: 4

June 27th, 2012 6:23pm

So, I did some checking and it looks like each user's contact card is in the exported XML multiple times. Here is an updated script that checks to see if the last user name that was printed is the same as the one that is currently being worked on, and if so it skips outputting the name. This is just a cosmetic change from the last version of the script.

# script to re-enable AD photos for users that have disabled them

# DNS Name of SQL Server - Leave Blank for SQL Server Express
$sqlserver = ''	

# This is the directory where exports will be placed temporarily - you must have write access to this directory
$exportdir = 'C:\Lync-Scripts'


########## DO NOT EDIT BELOW THIS LINE ##########

"Checking for Export Directory"
If (-not (Test-Path "$exportdir" -pathType container))
{
	"ERROR: Your Export Directory doesn't exist!"
	Exit
}

"Cleaning up old files..."
If (Test-Path "$exportdir\Export-Pictures.xml") { Remove-Item "$exportdir\Export-Pictures.xml" }
If (Test-Path "$exportdir\Import-Pictures.xml") { Remove-Item "$exportdir\Import-Pictures.xml" }

# check to see if we need to have an sqlserver argument to DBImpExp
If ($sqlserver -ne "")
{
	"Query will be run against SQL server ""$sqlserver"""
	$sqlserver = "/sqlserver:$sqlserver"
}

"Exporting users..."
$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/hrxmlfile:""$exportdir\Export-Pictures.xml"" /restype:user $sqlserver")
$p.WaitForExit()

# check that XML was exported
If (-not (Test-Path "$exportdir\Export-Pictures.xml" -pathType leaf))
{
	"ERROR: Verify that $exportdir is writable!"
	Exit
}

"Loading XML"
$d = [xml] (Get-Content "$exportdir\Export-Pictures.xml")

"Processing..."
$changes = 0
$lastProcessedUser = $null
foreach ($hr in $d.HomedResources.HomedResource)
{
	$found = 0
	foreach ($c in $hr.Containers.Container)
	{
		foreach ($p in $c.Publication)
		{
			If ($p.CategoryName -eq 'contactCard' -and $p.InstanceNum -eq 6 -and $p.Data.contactCard.displayADPhoto -eq 'false')
			{
				If ($hr.UserAtHost -ne $lastProcessedUser)
				{
					"$($hr.UserAtHost) reset"
					$lastProcessedUser = $hr.UserAtHost
				}
				$p.Data.contactCard.displayADPhoto = 'true'
				$p.Version = (([int] $p.Version) + 1).ToString()
				$p.PrevPubTime = $p.LastPubTime
				$p.LastPubTime = (Get-Date -Format s).ToString()
				$found = 1
				$changes++
			}
		}
	}
	If ($found -eq 0) { [Void]$d.HomedResources.RemoveChild($hr) }
}

"Changes: $changes"
If ($changes -ne 0)
{
	"Saving XML..."
	$d.Save("$exportdir\Import-Pictures.xml")

	"Importing users..."
	$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/import /hrxmlfile:""$exportdir\Import-Pictures.xml"" /restype:user $sqlserver")
	$p.WaitForExit()
}

"Finished import, cleaning up..."
If (Test-Path "$exportdir\Export-Pictures.xml") { Remove-Item "$exportdir\Export-Pictures.xml" }
If (Test-Path "$exportdir\Import-Pictures.xml") { Remove-Item "$exportdir\Import-Pictures.xml" }

"Done"

  • Proposed as answer by Arricc Tuesday, July 17, 2012 11:18 AM
Free Windows Admin Tool Kit Click here and download it now
June 27th, 2012 9:05pm

So, I did some checking and it looks like each user's contact card is in the exported XML multiple times. Here is an updated script that checks to see if the last user name that was printed is the same as the one that is currently being worked on, and if so it skips outputting the name. This is just a cosmetic change from the last version of the script.

# script to re-enable AD photos for users that have disabled them

# DNS Name of SQL Server - Leave Blank for SQL Server Express
$sqlserver = ''	

# This is the directory where exports will be placed temporarily - you must have write access to this directory
$exportdir = 'C:\Lync-Scripts'


########## DO NOT EDIT BELOW THIS LINE ##########

"Checking for Export Directory"
If (-not (Test-Path "$exportdir" -pathType container))
{
	"ERROR: Your Export Directory doesn't exist!"
	Exit
}

"Cleaning up old files..."
If (Test-Path "$exportdir\Export-Pictures.xml") { Remove-Item "$exportdir\Export-Pictures.xml" }
If (Test-Path "$exportdir\Import-Pictures.xml") { Remove-Item "$exportdir\Import-Pictures.xml" }

# check to see if we need to have an sqlserver argument to DBImpExp
If ($sqlserver -ne "")
{
	"Query will be run against SQL server ""$sqlserver"""
	$sqlserver = "/sqlserver:$sqlserver"
}

"Exporting users..."
$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/hrxmlfile:""$exportdir\Export-Pictures.xml"" /restype:user $sqlserver")
$p.WaitForExit()

# check that XML was exported
If (-not (Test-Path "$exportdir\Export-Pictures.xml" -pathType leaf))
{
	"ERROR: Verify that $exportdir is writable!"
	Exit
}

"Loading XML"
$d = [xml] (Get-Content "$exportdir\Export-Pictures.xml")

"Processing..."
$changes = 0
$lastProcessedUser = $null
foreach ($hr in $d.HomedResources.HomedResource)
{
	$found = 0
	foreach ($c in $hr.Containers.Container)
	{
		foreach ($p in $c.Publication)
		{
			If ($p.CategoryName -eq 'contactCard' -and $p.InstanceNum -eq 6 -and $p.Data.contactCard.displayADPhoto -eq 'false')
			{
				If ($hr.UserAtHost -ne $lastProcessedUser)
				{
					"$($hr.UserAtHost) reset"
					$lastProcessedUser = $hr.UserAtHost
				}
				$p.Data.contactCard.displayADPhoto = 'true'
				$p.Version = (([int] $p.Version) + 1).ToString()
				$p.PrevPubTime = $p.LastPubTime
				$p.LastPubTime = (Get-Date -Format s).ToString()
				$found = 1
				$changes++
			}
		}
	}
	If ($found -eq 0) { [Void]$d.HomedResources.RemoveChild($hr) }
}

"Changes: $changes"
If ($changes -ne 0)
{
	"Saving XML..."
	$d.Save("$exportdir\Import-Pictures.xml")

	"Importing users..."
	$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/import /hrxmlfile:""$exportdir\Import-Pictures.xml"" /restype:user $sqlserver")
	$p.WaitForExit()
}

"Finished import, cleaning up..."
If (Test-Path "$exportdir\Export-Pictures.xml") { Remove-Item "$exportdir\Export-Pictures.xml" }
If (Test-Path "$exportdir\Import-Pictures.xml") { Remove-Item "$exportdir\Import-Pictures.xml" }

"Done"

  • Proposed as answer by Arricc Tuesday, July 17, 2012 11:18 AM
June 27th, 2012 9:05pm

So, I did some checking and it looks like each user's contact card is in the exported XML multiple times. Here is an updated script that checks to see if the last user name that was printed is the same as the one that is currently being worked on, and if so it skips outputting the name. This is just a cosmetic change from the last version of the script.

# script to re-enable AD photos for users that have disabled them

# DNS Name of SQL Server - Leave Blank for SQL Server Express
$sqlserver = ''	

# This is the directory where exports will be placed temporarily - you must have write access to this directory
$exportdir = 'C:\Lync-Scripts'


########## DO NOT EDIT BELOW THIS LINE ##########

"Checking for Export Directory"
If (-not (Test-Path "$exportdir" -pathType container))
{
	"ERROR: Your Export Directory doesn't exist!"
	Exit
}

"Cleaning up old files..."
If (Test-Path "$exportdir\Export-Pictures.xml") { Remove-Item "$exportdir\Export-Pictures.xml" }
If (Test-Path "$exportdir\Import-Pictures.xml") { Remove-Item "$exportdir\Import-Pictures.xml" }

# check to see if we need to have an sqlserver argument to DBImpExp
If ($sqlserver -ne "")
{
	"Query will be run against SQL server ""$sqlserver"""
	$sqlserver = "/sqlserver:$sqlserver"
}

"Exporting users..."
$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/hrxmlfile:""$exportdir\Export-Pictures.xml"" /restype:user $sqlserver")
$p.WaitForExit()

# check that XML was exported
If (-not (Test-Path "$exportdir\Export-Pictures.xml" -pathType leaf))
{
	"ERROR: Verify that $exportdir is writable!"
	Exit
}

"Loading XML"
$d = [xml] (Get-Content "$exportdir\Export-Pictures.xml")

"Processing..."
$changes = 0
$lastProcessedUser = $null
foreach ($hr in $d.HomedResources.HomedResource)
{
	$found = 0
	foreach ($c in $hr.Containers.Container)
	{
		foreach ($p in $c.Publication)
		{
			If ($p.CategoryName -eq 'contactCard' -and $p.InstanceNum -eq 6 -and $p.Data.contactCard.displayADPhoto -eq 'false')
			{
				If ($hr.UserAtHost -ne $lastProcessedUser)
				{
					"$($hr.UserAtHost) reset"
					$lastProcessedUser = $hr.UserAtHost
				}
				$p.Data.contactCard.displayADPhoto = 'true'
				$p.Version = (([int] $p.Version) + 1).ToString()
				$p.PrevPubTime = $p.LastPubTime
				$p.LastPubTime = (Get-Date -Format s).ToString()
				$found = 1
				$changes++
			}
		}
	}
	If ($found -eq 0) { [Void]$d.HomedResources.RemoveChild($hr) }
}

"Changes: $changes"
If ($changes -ne 0)
{
	"Saving XML..."
	$d.Save("$exportdir\Import-Pictures.xml")

	"Importing users..."
	$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/import /hrxmlfile:""$exportdir\Import-Pictures.xml"" /restype:user $sqlserver")
	$p.WaitForExit()
}

"Finished import, cleaning up..."
If (Test-Path "$exportdir\Export-Pictures.xml") { Remove-Item "$exportdir\Export-Pictures.xml" }
If (Test-Path "$exportdir\Import-Pictures.xml") { Remove-Item "$exportdir\Import-Pictures.xml" }

"Done"

  • Proposed as answer by Arricc Tuesday, July 17, 2012 11:18 AM
Free Windows Admin Tool Kit Click here and download it now
June 27th, 2012 9:05pm

So, I did some checking and it looks like each user's contact card is in the exported XML multiple times. Here is an updated script that checks to see if the last user name that was printed is the same as the one that is currently being worked on, and if so it skips outputting the name. This is just a cosmetic change from the last version of the script.

# script to re-enable AD photos for users that have disabled them

# DNS Name of SQL Server - Leave Blank for SQL Server Express
$sqlserver = ''	

# This is the directory where exports will be placed temporarily - you must have write access to this directory
$exportdir = 'C:\Lync-Scripts'


########## DO NOT EDIT BELOW THIS LINE ##########

"Checking for Export Directory"
If (-not (Test-Path "$exportdir" -pathType container))
{
	"ERROR: Your Export Directory doesn't exist!"
	Exit
}

"Cleaning up old files..."
If (Test-Path "$exportdir\Export-Pictures.xml") { Remove-Item "$exportdir\Export-Pictures.xml" }
If (Test-Path "$exportdir\Import-Pictures.xml") { Remove-Item "$exportdir\Import-Pictures.xml" }

# check to see if we need to have an sqlserver argument to DBImpExp
If ($sqlserver -ne "")
{
	"Query will be run against SQL server ""$sqlserver"""
	$sqlserver = "/sqlserver:$sqlserver"
}

"Exporting users..."
$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/hrxmlfile:""$exportdir\Export-Pictures.xml"" /restype:user $sqlserver")
$p.WaitForExit()

# check that XML was exported
If (-not (Test-Path "$exportdir\Export-Pictures.xml" -pathType leaf))
{
	"ERROR: Verify that $exportdir is writable!"
	Exit
}

"Loading XML"
$d = [xml] (Get-Content "$exportdir\Export-Pictures.xml")

"Processing..."
$changes = 0
$lastProcessedUser = $null
foreach ($hr in $d.HomedResources.HomedResource)
{
	$found = 0
	foreach ($c in $hr.Containers.Container)
	{
		foreach ($p in $c.Publication)
		{
			If ($p.CategoryName -eq 'contactCard' -and $p.InstanceNum -eq 6 -and $p.Data.contactCard.displayADPhoto -eq 'false')
			{
				If ($hr.UserAtHost -ne $lastProcessedUser)
				{
					"$($hr.UserAtHost) reset"
					$lastProcessedUser = $hr.UserAtHost
				}
				$p.Data.contactCard.displayADPhoto = 'true'
				$p.Version = (([int] $p.Version) + 1).ToString()
				$p.PrevPubTime = $p.LastPubTime
				$p.LastPubTime = (Get-Date -Format s).ToString()
				$found = 1
				$changes++
			}
		}
	}
	If ($found -eq 0) { [Void]$d.HomedResources.RemoveChild($hr) }
}

"Changes: $changes"
If ($changes -ne 0)
{
	"Saving XML..."
	$d.Save("$exportdir\Import-Pictures.xml")

	"Importing users..."
	$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/import /hrxmlfile:""$exportdir\Import-Pictures.xml"" /restype:user $sqlserver")
	$p.WaitForExit()
}

"Finished import, cleaning up..."
If (Test-Path "$exportdir\Export-Pictures.xml") { Remove-Item "$exportdir\Export-Pictures.xml" }
If (Test-Path "$exportdir\Import-Pictures.xml") { Remove-Item "$exportdir\Import-Pictures.xml" }

"Done"

  • Proposed as answer by Arricc Tuesday, July 17, 2012 11:18 AM
June 27th, 2012 9:05pm

So, I did some checking and it looks like each user's contact card is in the exported XML multiple times. Here is an updated script that checks to see if the last user name that was printed is the same as the one that is currently being worked on, and if so it skips outputting the name. This is just a cosmetic change from the last version of the script.

# script to re-enable AD photos for users that have disabled them

# DNS Name of SQL Server - Leave Blank for SQL Server Express
$sqlserver = ''	

# This is the directory where exports will be placed temporarily - you must have write access to this directory
$exportdir = 'C:\Lync-Scripts'


########## DO NOT EDIT BELOW THIS LINE ##########

"Checking for Export Directory"
If (-not (Test-Path "$exportdir" -pathType container))
{
	"ERROR: Your Export Directory doesn't exist!"
	Exit
}

"Cleaning up old files..."
If (Test-Path "$exportdir\Export-Pictures.xml") { Remove-Item "$exportdir\Export-Pictures.xml" }
If (Test-Path "$exportdir\Import-Pictures.xml") { Remove-Item "$exportdir\Import-Pictures.xml" }

# check to see if we need to have an sqlserver argument to DBImpExp
If ($sqlserver -ne "")
{
	"Query will be run against SQL server ""$sqlserver"""
	$sqlserver = "/sqlserver:$sqlserver"
}

"Exporting users..."
$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/hrxmlfile:""$exportdir\Export-Pictures.xml"" /restype:user $sqlserver")
$p.WaitForExit()

# check that XML was exported
If (-not (Test-Path "$exportdir\Export-Pictures.xml" -pathType leaf))
{
	"ERROR: Verify that $exportdir is writable!"
	Exit
}

"Loading XML"
$d = [xml] (Get-Content "$exportdir\Export-Pictures.xml")

"Processing..."
$changes = 0
$lastProcessedUser = $null
foreach ($hr in $d.HomedResources.HomedResource)
{
	$found = 0
	foreach ($c in $hr.Containers.Container)
	{
		foreach ($p in $c.Publication)
		{
			If ($p.CategoryName -eq 'contactCard' -and $p.InstanceNum -eq 6 -and $p.Data.contactCard.displayADPhoto -eq 'false')
			{
				If ($hr.UserAtHost -ne $lastProcessedUser)
				{
					"$($hr.UserAtHost) reset"
					$lastProcessedUser = $hr.UserAtHost
				}
				$p.Data.contactCard.displayADPhoto = 'true'
				$p.Version = (([int] $p.Version) + 1).ToString()
				$p.PrevPubTime = $p.LastPubTime
				$p.LastPubTime = (Get-Date -Format s).ToString()
				$found = 1
				$changes++
			}
		}
	}
	If ($found -eq 0) { [Void]$d.HomedResources.RemoveChild($hr) }
}

"Changes: $changes"
If ($changes -ne 0)
{
	"Saving XML..."
	$d.Save("$exportdir\Import-Pictures.xml")

	"Importing users..."
	$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/import /hrxmlfile:""$exportdir\Import-Pictures.xml"" /restype:user $sqlserver")
	$p.WaitForExit()
}

"Finished import, cleaning up..."
If (Test-Path "$exportdir\Export-Pictures.xml") { Remove-Item "$exportdir\Export-Pictures.xml" }
If (Test-Path "$exportdir\Import-Pictures.xml") { Remove-Item "$exportdir\Import-Pictures.xml" }

"Done"

  • Proposed as answer by Arricc Tuesday, July 17, 2012 11:18 AM
Free Windows Admin Tool Kit Click here and download it now
June 27th, 2012 9:05pm

So, I did some checking and it looks like each user's contact card is in the exported XML multiple times. Here is an updated script that checks to see if the last user name that was printed is the same as the one that is currently being worked on, and if so it skips outputting the name. This is just a cosmetic change from the last version of the script.

# script to re-enable AD photos for users that have disabled them

# DNS Name of SQL Server - Leave Blank for SQL Server Express
$sqlserver = ''	

# This is the directory where exports will be placed temporarily - you must have write access to this directory
$exportdir = 'C:\Lync-Scripts'


########## DO NOT EDIT BELOW THIS LINE ##########

"Checking for Export Directory"
If (-not (Test-Path "$exportdir" -pathType container))
{
	"ERROR: Your Export Directory doesn't exist!"
	Exit
}

"Cleaning up old files..."
If (Test-Path "$exportdir\Export-Pictures.xml") { Remove-Item "$exportdir\Export-Pictures.xml" }
If (Test-Path "$exportdir\Import-Pictures.xml") { Remove-Item "$exportdir\Import-Pictures.xml" }

# check to see if we need to have an sqlserver argument to DBImpExp
If ($sqlserver -ne "")
{
	"Query will be run against SQL server ""$sqlserver"""
	$sqlserver = "/sqlserver:$sqlserver"
}

"Exporting users..."
$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/hrxmlfile:""$exportdir\Export-Pictures.xml"" /restype:user $sqlserver")
$p.WaitForExit()

# check that XML was exported
If (-not (Test-Path "$exportdir\Export-Pictures.xml" -pathType leaf))
{
	"ERROR: Verify that $exportdir is writable!"
	Exit
}

"Loading XML"
$d = [xml] (Get-Content "$exportdir\Export-Pictures.xml")

"Processing..."
$changes = 0
$lastProcessedUser = $null
foreach ($hr in $d.HomedResources.HomedResource)
{
	$found = 0
	foreach ($c in $hr.Containers.Container)
	{
		foreach ($p in $c.Publication)
		{
			If ($p.CategoryName -eq 'contactCard' -and $p.InstanceNum -eq 6 -and $p.Data.contactCard.displayADPhoto -eq 'false')
			{
				If ($hr.UserAtHost -ne $lastProcessedUser)
				{
					"$($hr.UserAtHost) reset"
					$lastProcessedUser = $hr.UserAtHost
				}
				$p.Data.contactCard.displayADPhoto = 'true'
				$p.Version = (([int] $p.Version) + 1).ToString()
				$p.PrevPubTime = $p.LastPubTime
				$p.LastPubTime = (Get-Date -Format s).ToString()
				$found = 1
				$changes++
			}
		}
	}
	If ($found -eq 0) { [Void]$d.HomedResources.RemoveChild($hr) }
}

"Changes: $changes"
If ($changes -ne 0)
{
	"Saving XML..."
	$d.Save("$exportdir\Import-Pictures.xml")

	"Importing users..."
	$p = [diagnostics.process]::start('"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\DBImpExp.exe"', "/import /hrxmlfile:""$exportdir\Import-Pictures.xml"" /restype:user $sqlserver")
	$p.WaitForExit()
}

"Finished import, cleaning up..."
If (Test-Path "$exportdir\Export-Pictures.xml") { Remove-Item "$exportdir\Export-Pictures.xml" }
If (Test-Path "$exportdir\Import-Pictures.xml") { Remove-Item "$exportdir\Import-Pictures.xml" }

"Done"

June 28th, 2012 12:05am

Hey Shannon / Guys

Just wanted to add frustration that users can still disable they picture which defeats the entire object of forcing it.

However, the script works great, so we just run it now every couple of hours for good measure.

Thanks for the script. Its much appreciated

Lets hope MS fix this in the next patch cycle!

Andy

Free Windows Admin Tool Kit Click here and download it now
June 29th, 2012 10:44am

Hey Shannon / Guys

Just wanted to add frustration that users can still disable they picture which defeats the entire object of forcing it.

However, the script works great, so we just run it now every couple of hours for good measure.

Thanks for the script. Its much appreciated

Lets hope MS fix this in the next patch cycle!

Andy


That's what we do as well, we find that users get sick of disabling the picture after a while and then the problem solves itself. Another thing we've done that seemed to help was to allow users to submit their own photo to use... when they pick it they seem to be more accepting of having it out there.
June 29th, 2012 7:01pm

Just to add my 2p:

Same problem here. 3000+ users.

Free Windows Admin Tool Kit Click here and download it now
July 17th, 2012 2:24pm

Same problem. 1000+ users
August 2nd, 2012 3:46pm

Another bump.  3500+ users for our agency alone, but when the entire State adopts Lync 2010 in the global directory, that would be 22,000+.
Free Windows Admin Tool Kit Click here and download it now
August 10th, 2012 8:50pm

Another bump.  3500+ users for our agency alone, but when the entire State adopts Lync 2010 in the global directory, that would be 22,000+.
August 10th, 2012 8:50pm

Another bump.  3500+ users for our agency alone, but when the entire State adopts Lync 2010 in the global directory, that would be 22,000+.
Free Windows Admin Tool Kit Click here and download it now
August 10th, 2012 8:50pm

Another bump.  3500+ users for our agency alone, but when the entire State adopts Lync 2010 in the global directory, that would be 22,000+.
August 10th, 2012 8:50pm

Another bump.  3500+ users for our agency alone, but when the entire State adopts Lync 2010 in the global directory, that would be 22,000+.
Free Windows Admin Tool Kit Click here and download it now
August 10th, 2012 8:50pm

Another bump.  3500+ users for our agency alone, but when the entire State adopts Lync 2010 in the global directory, that would be 22,000+.
August 10th, 2012 11:50pm

Same here. There are plans that within a few years the entire public sector of our devolved government will be in a single directory. That inlcudes health services, education services (both futher education, and higher eductation and schools), local government and councils, police forces, various QUANGOs. Literally hundreds of thousands of workers spread over 1000s of sites over more than 8000 square miles. We are having great sucess with the script above that we run every 5 mins, all day, every day but I am pretty sure that that kind of script/solution can't scale to something that large, or something in the cloud.

Good news however is there appears to be an inline policy to stop the user disabling the picture in Lync 2013!

Free Windows Admin Tool Kit Click here and download it now
August 11th, 2012 1:45pm

Same issue. 2000+ users affected...

October 12th, 2012 11:45pm

PhotosFromADOnly working, but this is not enough.  500 users will be affected.  Need to be able to disable "Do not show my picture".  Script from Shannon with comments worked great.  thanks.
Free Windows Admin Tool Kit Click here and download it now
November 6th, 2012 3:11pm

PhotosFromADOnly working, but this is not enough.  500 users will be affected.  Need to be able to disable "Do not show my picture".  Script from Shannon with comments worked great.  thanks.
November 6th, 2012 3:11pm

PhotosFromADOnly working, but this is not enough.  500 users will be affected.  Need to be able to disable "Do not show my picture".  Script from Shannon with comments worked great.  thanks.
Free Windows Admin Tool Kit Click here and download it now
November 6th, 2012 3:11pm

PhotosFromADOnly working, but this is not enough.  500 users will be affected.  Need to be able to disable "Do not show my picture".  Script from Shannon with comments worked great.  thanks.
November 6th, 2012 3:11pm

PhotosFromADOnly working, but this is not enough.  500 users will be affected.  Need to be able to disable "Do not show my picture".  Script from Shannon with comments worked great.  thanks.
Free Windows Admin Tool Kit Click here and download it now
November 6th, 2012 3:11pm

PhotosFromADOnly working, but this is not enough.  500 users will be affected.  Need to be able to disable "Do not show my picture".  Script from Shannon with comments worked great.  thanks.
November 6th, 2012 6:11pm

I was using this workaround in Lync 2010, but after migrating to 2013 this workaround no longer works. Lync 2013 has deprecated DMImpExp.exe and therefore is no longer included. There are native Lync Manangement Shell commands for this function but it exports the data in a ZIP file instead of the XML file. 
Free Windows Admin Tool Kit Click here and download it now
November 28th, 2012 7:02pm

Backup and Test Before Use On a Production System - NOT Supported by Microsoft

This is a workaround for Lync 2013 (could be modified easily for 2010 as well)

The following powershell command will directly update the appropriate database record on each FrontEnd server of a given pool.

$domain = 'your domain name here'

  (Get-CsPool (Get-CsComputer "$(hostname).$domain").Pool).Computers | % {
    Invoke-Sqlcmd -Query "update rtc.dbo.PublishedStaticInstance Set Data = CONVERT(image,convert(varbinary(4000),REPLACE(convert(varchar(4000),convert(varbinary(4000),Data)),'<displayADPhoto>false</displayADPhoto>','<displayADPhoto>true</displayADPhoto>'))) where convert(varchar(4000),convert(varbinary(4000),Data)) like '%<displayADPhoto>false</displayADPhoto>%';" -ServerInstance "$($_)\RTCLOCAL"
  }

Credit for SQL to: http://www.sipstories.com/2012/05/07/really-controlling-which-pictures-your-users-display-in-lync/

If someone knows how to initiate a sync between hosts for this table please let me know as it would be preferable to only connect to and update a single front end.







November 28th, 2012 10:52pm

Backup and Test Before Use On a Production System - NOT Supported by Microsoft

This is a workaround for Lync 2013 (could be modified easily for 2010 as well)

The following powershell command will directly update the appropriate database record on each FrontEnd server of a given pool.

$domain = 'your domain name here'

  (Get-CsPool (Get-CsComputer "$(hostname).$domain").Pool).Computers | % {
    Invoke-Sqlcmd -Query "update rtc.dbo.PublishedStaticInstance Set Data = CONVERT(image,convert(varbinary(4000),REPLACE(convert(varchar(4000),convert(varbinary(4000),Data)),'<displayADPhoto>false</displayADPhoto>','<displayADPhoto>true</displayADPhoto>'))) where convert(varchar(4000),convert(varbinary(4000),Data)) like '%<displayADPhoto>false</displayADPhoto>%';" -ServerInstance "$($_)\RTCLOCAL"
  }

Credit for SQL to: http://www.sipstories.com/2012/05/07/really-controlling-which-pictures-your-users-display-in-lync/

If someone knows how to initiate a sync between hosts for this table please let me know as it would be preferable to only connect to and update a single front end.







Free Windows Admin Tool Kit Click here and download it now
November 28th, 2012 10:52pm

Backup and Test Before Use On a Production System - NOT Supported by Microsoft

This is a workaround for Lync 2013 (could be modified easily for 2010 as well)

The following powershell command will directly update the appropriate database record on each FrontEnd server of a given pool.

$domain = 'your domain name here'

  (Get-CsPool (Get-CsComputer "$(hostname).$domain").Pool).Computers | % {
    Invoke-Sqlcmd -Query "update rtc.dbo.PublishedStaticInstance Set Data = CONVERT(image,convert(varbinary(4000),REPLACE(convert(varchar(4000),convert(varbinary(4000),Data)),'<displayADPhoto>false</displayADPhoto>','<displayADPhoto>true</displayADPhoto>'))) where convert(varchar(4000),convert(varbinary(4000),Data)) like '%<displayADPhoto>false</displayADPhoto>%';" -ServerInstance "$($_)\RTCLOCAL"
  }

Credit for SQL to: http://www.sipstories.com/2012/05/07/really-controlling-which-pictures-your-users-display-in-lync/

If someone knows how to initiate a sync between hosts for this table please let me know as it would be preferable to only connect to and update a single front end.







November 28th, 2012 10:52pm

Backup and Test Before Use On a Production System - NOT Supported by Microsoft

This is a workaround for Lync 2013 (could be modified easily for 2010 as well)

The following powershell command will directly update the appropriate database record on each FrontEnd server of a given pool.

$domain = 'your domain name here'

  (Get-CsPool (Get-CsComputer "$(hostname).$domain").Pool).Computers | % {
    Invoke-Sqlcmd -Query "update rtc.dbo.PublishedStaticInstance Set Data = CONVERT(image,convert(varbinary(4000),REPLACE(convert(varchar(4000),convert(varbinary(4000),Data)),'<displayADPhoto>false</displayADPhoto>','<displayADPhoto>true</displayADPhoto>'))) where convert(varchar(4000),convert(varbinary(4000),Data)) like '%<displayADPhoto>false</displayADPhoto>%';" -ServerInstance "$($_)\RTCLOCAL"
  }

Credit for SQL to: http://www.sipstories.com/2012/05/07/really-controlling-which-pictures-your-users-display-in-lync/

If someone knows how to initiate a sync between hosts for this table please let me know as it would be preferable to only connect to and update a single front end.







Free Windows Admin Tool Kit Click here and download it now
November 28th, 2012 10:52pm

Backup and Test Before Use On a Production System - NOT Supported by Microsoft

This is a workaround for Lync 2013 (could be modified easily for 2010 as well)

The following powershell command will directly update the appropriate database record on each FrontEnd server of a given pool.

$domain = 'your domain name here'

  (Get-CsPool (Get-CsComputer "$(hostname).$domain").Pool).Computers | % {
    Invoke-Sqlcmd -Query "update rtc.dbo.PublishedStaticInstance Set Data = CONVERT(image,convert(varbinary(4000),REPLACE(convert(varchar(4000),convert(varbinary(4000),Data)),'<displayADPhoto>false</displayADPhoto>','<displayADPhoto>true</displayADPhoto>'))) where convert(varchar(4000),convert(varbinary(4000),Data)) like '%<displayADPhoto>false</displayADPhoto>%';" -ServerInstance "$($_)\RTCLOCAL"
  }

Credit for SQL to: http://www.sipstories.com/2012/05/07/really-controlling-which-pictures-your-users-display-in-lync/

If someone knows how to initiate a sync between hosts for this table please let me know as it would be preferable to only connect to and update a single front end.







November 28th, 2012 10:52pm

Backup and Test Before Use On a Production System - NOT Supported by Microsoft

This is a workaround for Lync 2013 (could be modified easily for 2010 as well)

The following powershell command will directly update the appropriate database record on each FrontEnd server of a given pool.

$domain = 'your domain name here'

  (Get-CsPool (Get-CsComputer "$(hostname).$domain").Pool).Computers | % {
    Invoke-Sqlcmd -Query "update rtc.dbo.PublishedStaticInstance Set Data = CONVERT(image,convert(varbinary(4000),REPLACE(convert(varchar(4000),convert(varbinary(4000),Data)),'<displayADPhoto>false</displayADPhoto>','<displayADPhoto>true</displayADPhoto>'))) where convert(varchar(4000),convert(varbinary(4000),Data)) like '%<displayADPhoto>false</displayADPhoto>%';" -ServerInstance "$($_)\RTCLOCAL"
  }

Credit for SQL to: http://www.sipstories.com/2012/05/07/really-controlling-which-pictures-your-users-display-in-lync/

If someone knows how to initiate a sync between hosts for this table please let me know as it would be preferable to only connect to and update a single front end.







Free Windows Admin Tool Kit Click here and download it now
November 29th, 2012 1:52am

Hmm question as this likely makes a difference.

What type of deployment do you have? My script was being run against a Single Site Enterprise Deployment. Likely it might need alteration for Standard or for Multi-Site deployments.

Other than restarting my client I did not need to delete the profile.

The script as written was designed to run from one of the Front-End servers. If you running from an alternate host you'll need update some of the code to target one of your front-end servers.

"$(hostname).$domain"

changes to

"myfe1.domain.local'  <== your fqdn for a front end here

If on a host other than a Front-End it very likely would run but not do anything.

Also of note I'm running in Powershell 3.0 (via Windows 2012), which may or may not be a factor. Powershell 3.0 can be installed on Windows 7 and Windows 2008r2 which should get you far enough for the script to work from that aspect.

I presume you running on an account with Local Admin rights to the Lync servers as well. The script is logging into the RTCLOCAL sql instances which run on the Front-Ends

November 29th, 2012 6:18pm

Hmm question as this likely makes a difference.

What type of deployment do you have? My script was being run against a Single Site Enterprise Deployment. Likely it might need alteration for Standard or for Multi-Site deployments.

Other than restarting my client I did not need to delete the profile.

The script as written was designed to run from one of the Front-End servers. If you running from an alternate host you'll need update some of the code to target one of your front-end servers.

"$(hostname).$domain"

changes to

"myfe1.domain.local'  <== your fqdn for a front end here

If on a host other than a Front-End it very likely would run but not do anything.

Also of note I'm running in Powershell 3.0 (via Windows 2012), which may or may not be a factor. Powershell 3.0 can be installed on Windows 7 and Windows 2008r2 which should get you far enough for the script to work from that aspect.

I presume you running on an account with Local Admin rights to the Lync servers as well. The script is logging into the RTCLOCAL sql instances which run on the Front-Ends

Free Windows Admin Tool Kit Click here and download it now
November 29th, 2012 6:18pm

Hmm question as this likely makes a difference.

What type of deployment do you have? My script was being run against a Single Site Enterprise Deployment. Likely it might need alteration for Standard or for Multi-Site deployments.

Other than restarting my client I did not need to delete the profile.

The script as written was designed to run from one of the Front-End servers. If you running from an alternate host you'll need update some of the code to target one of your front-end servers.

"$(hostname).$domain"

changes to

"myfe1.domain.local'  <== your fqdn for a front end here

If on a host other than a Front-End it very likely would run but not do anything.

Also of note I'm running in Powershell 3.0 (via Windows 2012), which may or may not be a factor. Powershell 3.0 can be installed on Windows 7 and Windows 2008r2 which should get you far enough for the script to work from that aspect.

I presume you running on an account with Local Admin rights to the Lync servers as well. The script is logging into the RTCLOCAL sql instances which run on the Front-Ends

November 29th, 2012 6:18pm

Hmm question as this likely makes a difference.

What type of deployment do you have? My script was being run against a Single Site Enterprise Deployment. Likely it might need alteration for Standard or for Multi-Site deployments.

Other than restarting my client I did not need to delete the profile.

The script as written was designed to run from one of the Front-End servers. If you running from an alternate host you'll need update some of the code to target one of your front-end servers.

"$(hostname).$domain"

changes to

"myfe1.domain.local'  <== your fqdn for a front end here

If on a host other than a Front-End it very likely would run but not do anything.

Also of note I'm running in Powershell 3.0 (via Windows 2012), which may or may not be a factor. Powershell 3.0 can be installed on Windows 7 and Windows 2008r2 which should get you far enough for the script to work from that aspect.

I presume you running on an account with Local Admin rights to the Lync servers as well. The script is logging into the RTCLOCAL sql instances which run on the Front-Ends

Free Windows Admin Tool Kit Click here and download it now
November 29th, 2012 6:18pm

Hmm question as this likely makes a difference.

What type of deployment do you have? My script was being run against a Single Site Enterprise Deployment. Likely it might need alteration for Standard or for Multi-Site deployments.

Other than restarting my client I did not need to delete the profile.

The script as written was designed to run from one of the Front-End servers. If you running from an alternate host you'll need update some of the code to target one of your front-end servers.

"$(hostname).$domain"

changes to

"myfe1.domain.local'  <== your fqdn for a front end here

If on a host other than a Front-End it very likely would run but not do anything.

Also of note I'm running in Powershell 3.0 (via Windows 2012), which may or may not be a factor. Powershell 3.0 can be installed on Windows 7 and Windows 2008r2 which should get you far enough for the script to work from that aspect.

I presume you running on an account with Local Admin rights to the Lync servers as well. The script is logging into the RTCLOCAL sql instances which run on the Front-Ends

November 29th, 2012 6:18pm

Hi Michael,

I switched my user to No Picture in Lync, shut down my client, ran this in powershell on the FE server, deleted my SIP config profile off the client and restarted my Lync client. The setting was still set to No Picture. Im not really sure whats happening but it doesnt appear as its working. The script ran without error.

Free Windows Admin Tool Kit Click here and download it now
November 29th, 2012 8:38pm

Hmm question as this likely makes a difference.

What type of deployment do you have? My script was being run against a Single Site Enterprise Deployment. Likely it might need alteration for Standard or for Multi-Site deployments.

Other than restarting my client I did not need to delete the profile.

The script as written was designed to run from one of the Front-End servers. If you running from an alternate host you'll need update some of the code to target one of your front-end servers.

"$(hostname).$domain"

changes to

"myfe1.domain.local'  <== your fqdn for a front end here

If on a host other than a Front-End it very likely would run but not do anything.

Also of note I'm running in Powershell 3.0 (via Windows 2012), which may or may not be a factor. Powershell 3.0 can be installed on Windows 7 and Windows 2008r2 which should get you far enough for the script to work from that aspect.

I presume you running on an account with Local Admin rights to the Lync servers as well. The script is logging into the RTCLOCAL sql instances which run on the Front-Ends

November 29th, 2012 9:18pm

Its a Standard Edition Pool. I ran it from the FE pool server, which is on Server 2012 Standard. I will refer to the article you referenced for the SQL and see if I can get any results to show on screen. 
Free Windows Admin Tool Kit Click here and download it now
November 29th, 2012 10:47pm

Michael,

Your script is working flawlessly. Thank you. I verified it was working by logging onto the DB in SQL Studio and running the query....

select UserAtHost,convert(varchar(4000),convert(varbinary(4000),Data))
from PublishedStaticInstance,Resource
where ResourceId = PublisherId
and convert(varchar(4000),convert(varbinary(4000),Data))
like '%<displayADPhoto>%'

A before and after showed your script was changing the values as expected. I ran the Update-CsAddressBook command and now my client shows the AD picture selection again. I am not clear if that was required or if it was coincidence but the result is the same.

Thank you

November 29th, 2012 11:33pm

is there a solution for this now?
Free Windows Admin Tool Kit Click here and download it now
February 18th, 2013 4:12pm

There has been no development in the fundamental way Lync client works, so no. The work around is listed above.
February 18th, 2013 4:50pm

Be careful running the Powershell script above!

6,000 concurrent users logged on; single site, 1 enterprise pool, 3 FE's, SQL 2008R2 backend.

As a test, i set my Lync config to "Do Not Show Picture", ran this script from a FE server.  Dbimpexp.exe showed:

While "reindexing all tables and updating statistics" at least 1/3 (possibly more) of my user base saw the big ugly red banner message appear in their client, "Limited functionality is available due to outage" shown below.

At this point i'm still not sure what database(s) were reindexed.  Were they the ones hosted on the SQL cluster backend?  Or was it the the local db hosted on the FE where my SIP account is registered?  Searched the inet high and low trying to find an answer but couldn't.

Good news: as written above, the script works perfectly.  My setting was forced back to showing the default corporate picture after signing out then back in.

Bad news:  Can cause an outage.  Use at your own risk and definitely run it at off peak hours.


  • Edited by J.Kuta Tuesday, April 02, 2013 9:42 PM New Info
Free Windows Admin Tool Kit Click here and download it now
April 2nd, 2013 4:37pm

Be careful running the Powershell script above!

6,000 concurrent users logged on; single site, 1 enterprise pool, 3 FE's, SQL 2008R2 backend.

As a test, i set my Lync config to "Do Not Show Picture", ran this script from a FE server.  Dbimpexp.exe showed:

While "reindexing all tables and updating statistics" at least 1/3 (possibly more) of my user base saw the big ugly red banner message appear in their client, "Limited functionality is available due to outage" shown below.

At this point i'm still not sure what database(s) were reindexed.  Were they the ones hosted on the SQL cluster backend?  Or was it the the local db hosted on the FE where my SIP account is registered?  Searched the inet high and low trying to find an answer but couldn't.

Good news: as written above, the script works perfectly.  My setting was forced back to showing the default corporate picture after signing out then back in.

Bad news:  Can cause an outage.  Use at your own risk and definitely run it at off peak hours.


  • Edited by J.Kuta Tuesday, April 02, 2013 9:42 PM New Info
April 2nd, 2013 4:37pm

Be careful running the Powershell script above!

6,000 concurrent users logged on; single site, 1 enterprise pool, 3 FE's, SQL 2008R2 backend.

As a test, i set my Lync config to "Do Not Show Picture", ran this script from a FE server.  Dbimpexp.exe showed:

While "reindexing all tables and updating statistics" at least 1/3 (possibly more) of my user base saw the big ugly red banner message appear in their client, "Limited functionality is available due to outage" shown below.

At this point i'm still not sure what database(s) were reindexed.  Were they the ones hosted on the SQL cluster backend?  Or was it the the local db hosted on the FE where my SIP account is registered?  Searched the inet high and low trying to find an answer but couldn't.

Good news: as written above, the script works perfectly.  My setting was forced back to showing the default corporate picture after signing out then back in.

Bad news:  Can cause an outage.  Use at your own risk and definitely run it at off peak hours.


  • Edited by J.Kuta Tuesday, April 02, 2013 9:42 PM New Info
Free Windows Admin Tool Kit Click here and download it now
April 2nd, 2013 4:37pm

Be careful running the Powershell script above!

6,000 concurrent users logged on; single site, 1 enterprise pool, 3 FE's, SQL 2008R2 backend.

As a test, i set my Lync config to "Do Not Show Picture", ran this script from a FE server.  Dbimpexp.exe showed:

While "reindexing all tables and updating statistics" at least 1/3 (possibly more) of my user base saw the big ugly red banner message appear in their client, "Limited functionality is available due to outage" shown below.

At this point i'm still not sure what database(s) were reindexed.  Were they the ones hosted on the SQL cluster backend?  Or was it the the local db hosted on the FE where my SIP account is registered?  Searched the inet high and low trying to find an answer but couldn't.

Good news: as written above, the script works perfectly.  My setting was forced back to showing the default corporate picture after signing out then back in.

Bad news:  Can cause an outage.  Use at your own risk and definitely run it at off peak hours.


  • Edited by J.Kuta Tuesday, April 02, 2013 9:42 PM New Info
April 2nd, 2013 4:37pm

Be careful running the Powershell script above!

6,000 concurrent users logged on; single site, 1 enterprise pool, 3 FE's, SQL 2008R2 backend.

As a test, i set my Lync config to "Do Not Show Picture", ran this script from a FE server.  Dbimpexp.exe showed:

While "reindexing all tables and updating statistics" at least 1/3 (possibly more) of my user base saw the big ugly red banner message appear in their client, "Limited functionality is available due to outage" shown below.

At this point i'm still not sure what database(s) were reindexed.  Were they the ones hosted on the SQL cluster backend?  Or was it the the local db hosted on the FE where my SIP account is registered?  Searched the inet high and low trying to find an answer but couldn't.

Good news: as written above, the script works perfectly.  My setting was forced back to showing the default corporate picture after signing out then back in.

Bad news:  Can cause an outage.  Use at your own risk and definitely run it at off peak hours.


  • Edited by J.Kuta Tuesday, April 02, 2013 9:42 PM New Info
Free Windows Admin Tool Kit Click here and download it now
April 2nd, 2013 4:37pm

Be careful running the Powershell script above!

6,000 concurrent users logged on; single site, 1 enterprise pool, 3 FE's, SQL 2008R2 backend.

As a test, i set my Lync config to "Do Not Show Picture", ran this script from a FE server.  Dbimpexp.exe showed:

While "reindexing all tables and updating statistics" at least 1/3 (possibly more) of my user base saw the big ugly red banner message appear in their client, "Limited functionality is available due to outage" shown below.

At this point i'm still not sure what database(s) were reindexed.  Were they the ones hosted on the SQL cluster backend?  Or was it the the local db hosted on the FE where my SIP account is registered?  Searched the inet high and low trying to find an answer but couldn't.

Good news: as written above, the script works perfectly.  My setting was forced back to showing the default corporate picture after signing out then back in.

Bad news:  Can cause an outage.  Use at your own risk and definitely run it at off peak hours.


April 2nd, 2013 7:37pm

Indeed! Because Microsoft decided to store this data (incorrectly) in an image field it means that we have to extract the data on every record every time the script runs. That is a fairly intensive operation despite that data size being low. Image fields can not be indexed so you have to scan ALL of the records. I have over 1400 users in my database and it shows 100k records in that table takes about 2 seconds to complete running on a VM.

This might help (a lot):

Add a filter on [LastPubTime]

Assume you run the script once every 15 minutes you'd set the offset value to 15 minutes or if you want an overlap 20 minutes.

function Enable-UserPhotos ($Domain, $OffSet) {
  (Get-CsPool (Get-CsComputer "$(hostname).$Domain").Pool).Computers | % {
     Invoke-Sqlcmd -Query "update rtc.dbo.PublishedStaticInstance Set Data = CONVERT(image,convert(varbinary(4000),REPLACE(convert(varchar(4000),convert(varbinary(4000),Data)),'<displayADPhoto>false</displayADPhoto>','<displayADPhoto>true</displayADPhoto>'))) where [LastPubTime] >= DATEADD(mi,-$($OffSet),getdate()) AND convert(varchar(4000),convert(varbinary(4000),Data)) like '%<displayADPhoto>false</displayADPhoto>%';" -ServerInstance "$($_)\RTCLOCAL"
   }
}

Enable-UserPhotos -Domain 'your domain name here' -OffSet 15

Adding this filter should carve off a significant portion of the execution time of your query time per front end. Why? Because you'll only be checking the records that have changed within the Offset period that you specify. Even in an environment with 10k+ users your likely only looking at a very relatively small row set within that timeframe (relative to a full table scan). The more frequent the script runs the lower the time taken (to a point) I would not run this more often than every 5 minutes and recommend 15 - 60 minutes.. Mileage will very but I would not exceed 24 hours between for larger environment as the more users the longer time between the more potential records to parse.

The above WILL greatly reduce the chance of an outage due to index locks as seen by J.Kuta

Additionally disk performance will play in to this for large implementations the default location of these databases is C drive. More than likely you running either single spindle or a mirrored pair (same speed as a single). Moving these databases to a striped raid or raid5/6/10 will help desk performance. Memory too plays a big part in this.

Two things I typically do to every SQL server I touch:

  Check the Memory allocation
  Override 'Cost Threshold for Parellelism' (Advanced Tab for the sql instance)  to a value of 0

Memory is kind of a duh, the more memory the more data is held in memory. Lync tries to auto calculate based on available memory so that it doesn't fight with IIS. I recommend at least 4GB or larger for even a small system, adjust as makes sense.

'Cost Threshold for Parallelism'  I had a conversation with one the of the lead guys at Microsoft one day at a dynamics user conference and ask about this. Essentially this setting mostly a relic of the single core days of processors. Setting 0 makes SQL always consider using multiple threads and thus cpu. I typically see systems running at sustained 30-60% cpu utilization, drop in to the teens to single digits. SQL understands parallel processing, let it do its thing. Memory and disk plays in to this as well, simultaneous processes will use more memory. Faster processing will hit the disk harder as it can consume it faster.

Free Windows Admin Tool Kit Click here and download it now
April 2nd, 2013 10:18pm

Indeed! Because Microsoft decided to store this data (incorrectly) in an image field it means that we have to extract the data on every record every time the script runs. That is a fairly intensive operation despite that data size being low. Image fields can not be indexed so you have to scan ALL of the records. I have over 1400 users in my database and it shows 100k records in that table takes about 2 seconds to complete running on a VM.

This might help (a lot):

Add a filter on [LastPubTime]

Assume you run the script once every 15 minutes you'd set the offset value to 15 minutes or if you want an overlap 20 minutes.

function Enable-UserPhotos ($Domain, $OffSet) {
  (Get-CsPool (Get-CsComputer "$(hostname).$Domain").Pool).Computers | % {
     Invoke-Sqlcmd -Query "update rtc.dbo.PublishedStaticInstance Set Data = CONVERT(image,convert(varbinary(4000),REPLACE(convert(varchar(4000),convert(varbinary(4000),Data)),'<displayADPhoto>false</displayADPhoto>','<displayADPhoto>true</displayADPhoto>'))) where [LastPubTime] >= DATEADD(mi,-$($OffSet),getdate()) AND convert(varchar(4000),convert(varbinary(4000),Data)) like '%<displayADPhoto>false</displayADPhoto>%';" -ServerInstance "$($_)\RTCLOCAL"
   }
}

Enable-UserPhotos -Domain 'your domain name here' -OffSet 15

Adding this filter should carve off a significant portion of the execution time of your query time per front end. Why? Because you'll only be checking the records that have changed within the Offset period that you specify. Even in an environment with 10k+ users your likely only looking at a very relatively small row set within that timeframe (relative to a full table scan). The more frequent the script runs the lower the time taken (to a point) I would not run this more often than every 5 minutes and recommend 15 - 60 minutes.. Mileage will very but I would not exceed 24 hours between for larger environment as the more users the longer time between the more potential records to parse.

The above WILL greatly reduce the chance of an outage due to index locks as seen by J.Kuta

Additionally disk performance will play in to this for large implementations the default location of these databases is C drive. More than likely you running either single spindle or a mirrored pair (same speed as a single). Moving these databases to a striped raid or raid5/6/10 will help desk performance. Memory too plays a big part in this.

Two things I typically do to every SQL server I touch:

  Check the Memory allocation
  Override 'Cost Threshold for Parellelism' (Advanced Tab for the sql instance)  to a value of 0

Memory is kind of a duh, the more memory the more data is held in memory. Lync tries to auto calculate based on available memory so that it doesn't fight with IIS. I recommend at least 4GB or larger for even a small system, adjust as makes sense.

'Cost Threshold for Parallelism'  I had a conversation with one the of the lead guys at Microsoft one day at a dynamics user conference and ask about this. Essentially this setting mostly a relic of the single core days of processors. Setting 0 makes SQL always consider using multiple threads and thus cpu. I typically see systems running at sustained 30-60% cpu utilization, drop in to the teens to single digits. SQL understands parallel processing, let it do its thing. Memory and disk plays in to this as well, simultaneous processes will use more memory. Faster processing will hit the disk harder as it can consume it faster.

April 2nd, 2013 10:18pm

Indeed! Because Microsoft decided to store this data (incorrectly) in an image field it means that we have to extract the data on every record every time the script runs. That is a fairly intensive operation despite that data size being low. Image fields can not be indexed so you have to scan ALL of the records. I have over 1400 users in my database and it shows 100k records in that table takes about 2 seconds to complete running on a VM.

This might help (a lot):

Add a filter on [LastPubTime]

Assume you run the script once every 15 minutes you'd set the offset value to 15 minutes or if you want an overlap 20 minutes.

function Enable-UserPhotos ($Domain, $OffSet) {
  (Get-CsPool (Get-CsComputer "$(hostname).$Domain").Pool).Computers | % {
     Invoke-Sqlcmd -Query "update rtc.dbo.PublishedStaticInstance Set Data = CONVERT(image,convert(varbinary(4000),REPLACE(convert(varchar(4000),convert(varbinary(4000),Data)),'<displayADPhoto>false</displayADPhoto>','<displayADPhoto>true</displayADPhoto>'))) where [LastPubTime] >= DATEADD(mi,-$($OffSet),getdate()) AND convert(varchar(4000),convert(varbinary(4000),Data)) like '%<displayADPhoto>false</displayADPhoto>%';" -ServerInstance "$($_)\RTCLOCAL"
   }
}

Enable-UserPhotos -Domain 'your domain name here' -OffSet 15

Adding this filter should carve off a significant portion of the execution time of your query time per front end. Why? Because you'll only be checking the records that have changed within the Offset period that you specify. Even in an environment with 10k+ users your likely only looking at a very relatively small row set within that timeframe (relative to a full table scan). The more frequent the script runs the lower the time taken (to a point) I would not run this more often than every 5 minutes and recommend 15 - 60 minutes.. Mileage will very but I would not exceed 24 hours between for larger environment as the more users the longer time between the more potential records to parse.

The above WILL greatly reduce the chance of an outage due to index locks as seen by J.Kuta

Additionally disk performance will play in to this for large implementations the default location of these databases is C drive. More than likely you running either single spindle or a mirrored pair (same speed as a single). Moving these databases to a striped raid or raid5/6/10 will help desk performance. Memory too plays a big part in this.

Two things I typically do to every SQL server I touch:

  Check the Memory allocation
  Override 'Cost Threshold for Parellelism' (Advanced Tab for the sql instance)  to a value of 0

Memory is kind of a duh, the more memory the more data is held in memory. Lync tries to auto calculate based on available memory so that it doesn't fight with IIS. I recommend at least 4GB or larger for even a small system, adjust as makes sense.

'Cost Threshold for Parallelism'  I had a conversation with one the of the lead guys at Microsoft one day at a dynamics user conference and ask about this. Essentially this setting mostly a relic of the single core days of processors. Setting 0 makes SQL always consider using multiple threads and thus cpu. I typically see systems running at sustained 30-60% cpu utilization, drop in to the teens to single digits. SQL understands parallel processing, let it do its thing. Memory and disk plays in to this as well, simultaneous processes will use more memory. Faster processing will hit the disk harder as it can consume it faster.

Free Windows Admin Tool Kit Click here and download it now
April 2nd, 2013 10:18pm

Indeed! Because Microsoft decided to store this data (incorrectly) in an image field it means that we have to extract the data on every record every time the script runs. That is a fairly intensive operation despite that data size being low. Image fields can not be indexed so you have to scan ALL of the records. I have over 1400 users in my database and it shows 100k records in that table takes about 2 seconds to complete running on a VM.

This might help (a lot):

Add a filter on [LastPubTime]

Assume you run the script once every 15 minutes you'd set the offset value to 15 minutes or if you want an overlap 20 minutes.

function Enable-UserPhotos ($Domain, $OffSet) {
  (Get-CsPool (Get-CsComputer "$(hostname).$Domain").Pool).Computers | % {
     Invoke-Sqlcmd -Query "update rtc.dbo.PublishedStaticInstance Set Data = CONVERT(image,convert(varbinary(4000),REPLACE(convert(varchar(4000),convert(varbinary(4000),Data)),'<displayADPhoto>false</displayADPhoto>','<displayADPhoto>true</displayADPhoto>'))) where [LastPubTime] >= DATEADD(mi,-$($OffSet),getdate()) AND convert(varchar(4000),convert(varbinary(4000),Data)) like '%<displayADPhoto>false</displayADPhoto>%';" -ServerInstance "$($_)\RTCLOCAL"
   }
}

Enable-UserPhotos -Domain 'your domain name here' -OffSet 15

Adding this filter should carve off a significant portion of the execution time of your query time per front end. Why? Because you'll only be checking the records that have changed within the Offset period that you specify. Even in an environment with 10k+ users your likely only looking at a very relatively small row set within that timeframe (relative to a full table scan). The more frequent the script runs the lower the time taken (to a point) I would not run this more often than every 5 minutes and recommend 15 - 60 minutes.. Mileage will very but I would not exceed 24 hours between for larger environment as the more users the longer time between the more potential records to parse.

The above WILL greatly reduce the chance of an outage due to index locks as seen by J.Kuta

Additionally disk performance will play in to this for large implementations the default location of these databases is C drive. More than likely you running either single spindle or a mirrored pair (same speed as a single). Moving these databases to a striped raid or raid5/6/10 will help desk performance. Memory too plays a big part in this.

Two things I typically do to every SQL server I touch:

  Check the Memory allocation
  Override 'Cost Threshold for Parellelism' (Advanced Tab for the sql instance)  to a value of 0

Memory is kind of a duh, the more memory the more data is held in memory. Lync tries to auto calculate based on available memory so that it doesn't fight with IIS. I recommend at least 4GB or larger for even a small system, adjust as makes sense.

'Cost Threshold for Parallelism'  I had a conversation with one the of the lead guys at Microsoft one day at a dynamics user conference and ask about this. Essentially this setting mostly a relic of the single core days of processors. Setting 0 makes SQL always consider using multiple threads and thus cpu. I typically see systems running at sustained 30-60% cpu utilization, drop in to the teens to single digits. SQL understands parallel processing, let it do its thing. Memory and disk plays in to this as well, simultaneous processes will use more memory. Faster processing will hit the disk harder as it can consume it faster.

April 2nd, 2013 10:18pm

Indeed! Because Microsoft decided to store this data (incorrectly) in an image field it means that we have to extract the data on every record every time the script runs. That is a fairly intensive operation despite that data size being low. Image fields can not be indexed so you have to scan ALL of the records. I have over 1400 users in my database and it shows 100k records in that table takes about 2 seconds to complete running on a VM.

This might help (a lot):

Add a filter on [LastPubTime]

Assume you run the script once every 15 minutes you'd set the offset value to 15 minutes or if you want an overlap 20 minutes.

function Enable-UserPhotos ($Domain, $OffSet) {
  (Get-CsPool (Get-CsComputer "$(hostname).$Domain").Pool).Computers | % {
     Invoke-Sqlcmd -Query "update rtc.dbo.PublishedStaticInstance Set Data = CONVERT(image,convert(varbinary(4000),REPLACE(convert(varchar(4000),convert(varbinary(4000),Data)),'<displayADPhoto>false</displayADPhoto>','<displayADPhoto>true</displayADPhoto>'))) where [LastPubTime] >= DATEADD(mi,-$($OffSet),getdate()) AND convert(varchar(4000),convert(varbinary(4000),Data)) like '%<displayADPhoto>false</displayADPhoto>%';" -ServerInstance "$($_)\RTCLOCAL"
   }
}

Enable-UserPhotos -Domain 'your domain name here' -OffSet 15

Adding this filter should carve off a significant portion of the execution time of your query time per front end. Why? Because you'll only be checking the records that have changed within the Offset period that you specify. Even in an environment with 10k+ users your likely only looking at a very relatively small row set within that timeframe (relative to a full table scan). The more frequent the script runs the lower the time taken (to a point) I would not run this more often than every 5 minutes and recommend 15 - 60 minutes.. Mileage will very but I would not exceed 24 hours between for larger environment as the more users the longer time between the more potential records to parse.

The above WILL greatly reduce the chance of an outage due to index locks as seen by J.Kuta

Additionally disk performance will play in to this for large implementations the default location of these databases is C drive. More than likely you running either single spindle or a mirrored pair (same speed as a single). Moving these databases to a striped raid or raid5/6/10 will help desk performance. Memory too plays a big part in this.

Two things I typically do to every SQL server I touch:

  Check the Memory allocation
  Override 'Cost Threshold for Parellelism' (Advanced Tab for the sql instance)  to a value of 0

Memory is kind of a duh, the more memory the more data is held in memory. Lync tries to auto calculate based on available memory so that it doesn't fight with IIS. I recommend at least 4GB or larger for even a small system, adjust as makes sense.

'Cost Threshold for Parallelism'  I had a conversation with one the of the lead guys at Microsoft one day at a dynamics user conference and ask about this. Essentially this setting mostly a relic of the single core days of processors. Setting 0 makes SQL always consider using multiple threads and thus cpu. I typically see systems running at sustained 30-60% cpu utilization, drop in to the teens to single digits. SQL understands parallel processing, let it do its thing. Memory and disk plays in to this as well, simultaneous processes will use more memory. Faster processing will hit the disk harder as it can consume it faster.

Free Windows Admin Tool Kit Click here and download it now
April 2nd, 2013 10:18pm

Indeed! Because Microsoft decided to store this data (incorrectly) in an image field it means that we have to extract the data on every record every time the script runs. That is a fairly intensive operation despite that data size being low. Image fields can not be indexed so you have to scan ALL of the records. I have over 1400 users in my database and it shows 100k records in that table takes about 2 seconds to complete running on a VM.

This might help (a lot):

Add a filter on [LastPubTime]

Assume you run the script once every 15 minutes you'd set the offset value to 15 minutes or if you want an overlap 20 minutes.

function Enable-UserPhotos ($Domain, $OffSet) {
  (Get-CsPool (Get-CsComputer "$(hostname).$Domain").Pool).Computers | % {
     Invoke-Sqlcmd -Query "update rtc.dbo.PublishedStaticInstance Set Data = CONVERT(image,convert(varbinary(4000),REPLACE(convert(varchar(4000),convert(varbinary(4000),Data)),'<displayADPhoto>false</displayADPhoto>','<displayADPhoto>true</displayADPhoto>'))) where [LastPubTime] >= DATEADD(mi,-$($OffSet),getdate()) AND convert(varchar(4000),convert(varbinary(4000),Data)) like '%<displayADPhoto>false</displayADPhoto>%';" -ServerInstance "$($_)\RTCLOCAL"
   }
}

Enable-UserPhotos -Domain 'your domain name here' -OffSet 15

Adding this filter should carve off a significant portion of the execution time of your query time per front end. Why? Because you'll only be checking the records that have changed within the Offset period that you specify. Even in an environment with 10k+ users your likely only looking at a very relatively small row set within that timeframe (relative to a full table scan). The more frequent the script runs the lower the time taken (to a point) I would not run this more often than every 5 minutes and recommend 15 - 60 minutes.. Mileage will very but I would not exceed 24 hours between for larger environment as the more users the longer time between the more potential records to parse.

The above WILL greatly reduce the chance of an outage due to index locks as seen by J.Kuta

Additionally disk performance will play in to this for large implementations the default location of these databases is C drive. More than likely you running either single spindle or a mirrored pair (same speed as a single). Moving these databases to a striped raid or raid5/6/10 will help desk performance. Memory too plays a big part in this.

Two things I typically do to every SQL server I touch:

  Check the Memory allocation
  Override 'Cost Threshold for Parellelism' (Advanced Tab for the sql instance)  to a value of 0

Memory is kind of a duh, the more memory the more data is held in memory. Lync tries to auto calculate based on available memory so that it doesn't fight with IIS. I recommend at least 4GB or larger for even a small system, adjust as makes sense.

'Cost Threshold for Parallelism'  I had a conversation with one the of the lead guys at Microsoft one day at a dynamics user conference and ask about this. Essentially this setting mostly a relic of the single core days of processors. Setting 0 makes SQL always consider using multiple threads and thus cpu. I typically see systems running at sustained 30-60% cpu utilization, drop in to the teens to single digits. SQL understands parallel processing, let it do its thing. Memory and disk plays in to this as well, simultaneous processes will use more memory. Faster processing will hit the disk harder as it can consume it faster.

April 3rd, 2013 1:18am

At this point i'm still not sure what database(s) were reindexed.  Were they the ones hosted on the SQL cluster backend?  Or was it the the local db hosted on the FE where my SIP account is

I'm assuming you ran 'Display Estimate Execution Plan'?

Estimated Excution Plan

Keep in mind that this is cost not time which does not always an indicator of time. The real bulk of execution time is the 'Compute Scalar' as that's where the image conversion is occurring (I believe)

To more directly answer however the update occurs directly on each frontend in the LOCALRTC sql instance. So if one server takes 10 minutes and you have 15.. you'll be there a while. My previous post however should greatly reduce that time, hopefully to seconds in most cases.

Free Windows Admin Tool Kit Click here and download it now
April 3rd, 2013 7:29pm

At this point i'm still not sure what database(s) were reindexed.  Were they the ones hosted on the SQL cluster backend?  Or was it the the local db hosted on the FE where my SIP account is

I'm assuming you ran 'Display Estimate Execution Plan'?

Estimated Excution Plan

Keep in mind that this is cost not time which does not always an indicator of time. The real bulk of execution time is the 'Compute Scalar' as that's where the image conversion is occurring (I believe)

To more directly answer however the update occurs directly on each frontend in the LOCALRTC sql instance. So if one server takes 10 minutes and you have 15.. you'll be there a while. My previous post however should greatly reduce that time, hopefully to seconds in most cases.

April 3rd, 2013 7:29pm

At this point i'm still not sure what database(s) were reindexed.  Were they the ones hosted on the SQL cluster backend?  Or was it the the local db hosted on the FE where my SIP account is

I'm assuming you ran 'Display Estimate Execution Plan'?

Estimated Excution Plan

Keep in mind that this is cost not time which does not always an indicator of time. The real bulk of execution time is the 'Compute Scalar' as that's where the image conversion is occurring (I believe)

To more directly answer however the update occurs directly on each frontend in the LOCALRTC sql instance. So if one server takes 10 minutes and you have 15.. you'll be there a while. My previous post however should greatly reduce that time, hopefully to seconds in most cases.

Free Windows Admin Tool Kit Click here and download it now
April 3rd, 2013 7:29pm

At this point i'm still not sure what database(s) were reindexed.  Were they the ones hosted on the SQL cluster backend?  Or was it the the local db hosted on the FE where my SIP account is

I'm assuming you ran 'Display Estimate Execution Plan'?

Estimated Excution Plan

Keep in mind that this is cost not time which does not always an indicator of time. The real bulk of execution time is the 'Compute Scalar' as that's where the image conversion is occurring (I believe)

To more directly answer however the update occurs directly on each frontend in the LOCALRTC sql instance. So if one server takes 10 minutes and you have 15.. you'll be there a while. My previous post however should greatly reduce that time, hopefully to seconds in most cases.

April 3rd, 2013 7:29pm

At this point i'm still not sure what database(s) were reindexed.  Were they the ones hosted on the SQL cluster backend?  Or was it the the local db hosted on the FE where my SIP account is

I'm assuming you ran 'Display Estimate Execution Plan'?

Estimated Excution Plan

Keep in mind that this is cost not time which does not always an indicator of time. The real bulk of execution time is the 'Compute Scalar' as that's where the image conversion is occurring (I believe)

To more directly answer however the update occurs directly on each frontend in the LOCALRTC sql instance. So if one server takes 10 minutes and you have 15.. you'll be there a while. My previous post however should greatly reduce that time, hopefully to seconds in most cases.

Free Windows Admin Tool Kit Click here and download it now
April 3rd, 2013 7:29pm

At this point i'm still not sure what database(s) were reindexed.  Were they the ones hosted on the SQL cluster backend?  Or was it the the local db hosted on the FE where my SIP account is

I'm assuming you ran 'Display Estimate Execution Plan'?

Estimated Excution Plan

Keep in mind that this is cost not time which does not always an indicator of time. The real bulk of execution time is the 'Compute Scalar' as that's where the image conversion is occurring (I believe)

To more directly answer however the update occurs directly on each frontend in the LOCALRTC sql instance. So if one server takes 10 minutes and you have 15.. you'll be there a while. My previous post however should greatly reduce that time, hopefully to seconds in most cases.

April 3rd, 2013 10:29pm

Michael - thank you for your hard work on creating this script. I've implemented it in our environment, and found that the SQL query in your code block has an error due to syntax. Unless corrections below are made, the powershell script will run (without error) but will fail to modify the database because it passes an invalid SQL query. Here is the correction needed in your script block: 

# Incorrect SQL query implementation 
[LastPubTime] >= DATEADD(mi,-$($OffSet),getdate()) 
# Correct SQL query implementation
[LastPubTime] >= DATEADD(mi,-($OffSet),getdate()) 

Once the change is made, everything works perfectly well, and accomplishes the job.

Couldn't have done it without your hard work, and just wanted to save other users of this method some troubleshooting time.

Best,

Ilya


Free Windows Admin Tool Kit Click here and download it now
June 26th, 2013 4:32pm

Michael - thank you for your hard work on creating this script. I've implemented it in our environment, and found that the SQL query in your code block has an error due to syntax. Unless corrections below are made, the powershell script will run (without error) but will fail to modify the database because it passes an invalid SQL query. Here is the correction needed in your script block: 

# Incorrect SQL query implementation 
[LastPubTime] >= DATEADD(mi,-$($OffSet),getdate()) 
# Correct SQL query implementation
[LastPubTime] >= DATEADD(mi,-($OffSet),getdate()) 

Once the change is made, everything works perfectly well, and accomplishes the job.

Couldn't have done it without your hard work, and just wanted to save other users of this method some troubleshooting time.

Best,

Ilya


June 26th, 2013 4:32pm

Michael - thank you for your hard work on creating this script. I've implemented it in our environment, and found that the SQL query in your code block has an error due to syntax. Unless corrections below are made, the powershell script will run (without error) but will fail to modify the database because it passes an invalid SQL query. Here is the correction needed in your script block: 

# Incorrect SQL query implementation 
[LastPubTime] >= DATEADD(mi,-$($OffSet),getdate()) 
# Correct SQL query implementation
[LastPubTime] >= DATEADD(mi,-($OffSet),getdate()) 

Once the change is made, everything works perfectly well, and accomplishes the job.

Couldn't have done it without your hard work, and just wanted to save other users of this method some troubleshooting time.

Best,

Ilya


Free Windows Admin Tool Kit Click here and download it now
June 26th, 2013 4:32pm

Michael - thank you for your hard work on creating this script. I've implemented it in our environment, and found that the SQL query in your code block has an error due to syntax. Unless corrections below are made, the powershell script will run (without error) but will fail to modify the database because it passes an invalid SQL query. Here is the correction needed in your script block: 

# Incorrect SQL query implementation 
[LastPubTime] >= DATEADD(mi,-$($OffSet),getdate()) 
# Correct SQL query implementation
[LastPubTime] >= DATEADD(mi,-($OffSet),getdate()) 

Once the change is made, everything works perfectly well, and accomplishes the job.

Couldn't have done it without your hard work, and just wanted to save other users of this method some troubleshooting time.

Best,

Ilya


June 26th, 2013 4:32pm

Michael - thank you for your hard work on creating this script. I've implemented it in our environment, and found that the SQL query in your code block has an error due to syntax. Unless corrections below are made, the powershell script will run (without error) but will fail to modify the database because it passes an invalid SQL query. Here is the correction needed in your script block: 

# Incorrect SQL query implementation 
[LastPubTime] >= DATEADD(mi,-$($OffSet),getdate()) 
# Correct SQL query implementation
[LastPubTime] >= DATEADD(mi,-($OffSet),getdate()) 

Once the change is made, everything works perfectly well, and accomplishes the job.

Couldn't have done it without your hard work, and just wanted to save other users of this method some troubleshooting time.

Best,

Ilya


Free Windows Admin Tool Kit Click here and download it now
June 26th, 2013 4:32pm

Michael - thank you for your hard work on creating this script. I've implemented it in our environment, and found that the SQL query in your code block has an error due to syntax. Unless corrections below are made, the powershell script will run (without error) but will fail to modify the database because it passes an invalid SQL query. Here is the correction needed in your script block: 

# Incorrect SQL query implementation 
[LastPubTime] >= DATEADD(mi,-$($OffSet),getdate()) 
# Correct SQL query implementation
[LastPubTime] >= DATEADD(mi,-($OffSet),getdate()) 

Once the change is made, everything works perfectly well, and accomplishes the job.

Couldn't have done it without your hard work, and just wanted to save other users of this method some troubleshooting time.

Best,

Ilya


June 26th, 2013 7:32pm

Interesting may be a powershell version difference, what version of Powershell and what OS if I might ask? That said removing the $ should work for PS 1.0 through 3.0 just as well.

-$($OffSet) vs ,-($OffSet)

All that $() adds is a wrapper in powershell at the point it gets to SQL, assuming $OffSet = 15, it would look like -15. Wrapping in $() is normally used for more complex string inclusion, such as:

$Prefer = "blue"
$MyString = "My favorite color is $(if ($Prefer -ne $null) { $Prefer } else { "Purple" } ) but I like hot pink too"

Free Windows Admin Tool Kit Click here and download it now
June 26th, 2013 7:44pm

The environment is Lync 2013 (Front Ends on Win2k8 R2 Enterprise servers), and SQL databases colocated on the same. Lync 2013 requires Powershell 3 to be installed, so that is what I was working with in terms of versioning.

To find why the script wasn't working, I had to run the SQL query from the script manually from SQL Studio against the Lync database, and then checked why powershell wasn't piping the variable correctly. When you include the $() wrapper, it breaks the query, and if you just pipe the variable in as ($OffSet) it works like a charm.

Again, thanks for your efforts - I can't believe Microsoft doesn't include this as a configurable option out of the box, and we have to hack it this way.

Whatever gets the job done!

June 26th, 2013 9:10pm

Solution present in this thread!!!! 

It is work!!

Do not answer it again if you do not know the right answer!

Free Windows Admin Tool Kit Click here and download it now
July 10th, 2013 3:32pm


We added a suggestion for this feature on http://lync.ideascale.com/
so you can vote if you think "Admin level ability to disable "Hide My Picture" in Lync Client is needed:
http://lync.ideascale.com/a/dtd/Admin-level-ability-to-disable-Hide-My-Picture-in-Lync-Client/506026-16285?submitted=1
August 2nd, 2013 2:42pm

Minor Tweak for those who are executing from a machine other than a front end.

Note you need Lync powershell on the host still

function Enforce-UserPhotos ($Domain, $OffSet) {
  (Get-CsPool $Domain).computers | % {
     Invoke-Sqlcmd -Query "update rtc.dbo.PublishedStaticInstance Set Data = CONVERT(image,convert(varbinary(4000),REPLACE(convert(varchar(4000),convert(varbinary(4000),Data)),'<displayADPhoto>false</displayADPhoto>','<displayADPhoto>true</displayADPhoto>'))) where [LastPubTime] >= DATEADD(mi,-($OffSet),getdate()) AND convert(varchar(4000),convert(varbinary(4000),Data)) like '%<displayADPhoto>false</displayADPhoto>%';" -ServerInstance "$($_)\RTCLOCAL"
   }
}

Enforce-UserPhotos -Domain 'Front-End Pool FQDN' -OffSet 15


Free Windows Admin Tool Kit Click here and download it now
September 25th, 2013 2:28pm

130 users here that would really like the option.   Hard to believe it's not in Group Policy or the Lync Policy settings especially for such a app that is a completely "corporate" focused.

I had to do the Powershell command with a scheduled task as shown in the previous messages which works ok except it's messy.

Another beef is the way Microsoft stores the Lync settings in the SQL database.  I have been searching for the table that shows the Voice Dial Plan configuration for a while now...


  

October 8th, 2013 10:25pm

Anybody knows, does this feature implemented in Lync 2013 or still not? Thanks.
Free Windows Admin Tool Kit Click here and download it now
October 9th, 2013 8:02am

Functionality is unchanged in Lync 2013, this thread covers both 2010 and 2013 implementations of this workaround.
October 9th, 2013 5:33pm

Functionality is unchanged in Lync 2013, this thread covers both 2010 and 2013 implementations of this workaround.

I didn't find this to be true. I did however come up with a proven work-around. Please feel free to review, try it out, and leave feedback afterwards everyone. This is free, not a sales pitch :)

http://social.technet.microsoft.com/Forums/lync/en-US/23780cad-a365-4e88-a667-57f22558b60a/how-do-i-enforce-show-my-picture-instead-of-hide-my-picture-in-lync-server-2013?forum=lyncdeploy

Free Windows Admin Tool Kit Click here and download it now
October 31st, 2013 3:55pm

I have registered this feedback in the Lync feedback system internally. Will keep you guys posted. Please keep voting and updating the thread.
February 18th, 2014 1:55pm

I'm shocked by the amount of people here who feel the need to force users to do something, as if they are incapable of making decisions for themselves.  Obviously, your users don't want to show their photos, but somehow, you feel like it's the end of the world if they don't have it.  The reply about it being a security risk is laughable. If a user photo in lync is part of your security framework, then your security system is terrible.

Instead of trying to tyrannically force the world to your view, how about listening to your users and realizing that forcing them to show photos is a terrible idea?  Give them the choice.

Free Windows Admin Tool Kit Click here and download it now
May 22nd, 2014 5:51pm

I'm glad that you're in an environment where you have the luxury/ability to allow the users to choose.  However, when the CEO has mandated that all users will have their picture displayed in Windows/Outlook/Lync, etc., giving the user the choice is not an option.  Allowing the administrator to force that would make it much easier and a time-saver not having to 'police' it and/or always having to run a script to as a workaround.

May 22nd, 2014 6:10pm

That comment is laughable....You haven't worked in big corporate environments then have you?
Free Windows Admin Tool Kit Click here and download it now
June 25th, 2014 8:22am

Same Issue. 2,000 + Users

We need to stop our users from clicking "Hide my Photo".

We've been able to stop this on exchange and sharepoint, just not here.

July 1st, 2014 7:41pm

I never cease to be amused at how crappy Microsoft is at listening to its customers...

Free Windows Admin Tool Kit Click here and download it now
August 27th, 2014 1:40pm

Just for general awareness, can any of you please explain your business case for not allowing users to not display photos.

I personally do not find any significant value add to having a contact's photo displayed.

July 2nd, 2015 12:30pm

Is it work in Skype FB ?
Free Windows Admin Tool Kit Click here and download it now
July 17th, 2015 1:32am

Is it work in Skype FB ?
  • Edited by banzalini Friday, July 17, 2015 5:37 AM
July 17th, 2015 5:32am

Is it work in Skype FB ?
  • Edited by banzalini Friday, July 17, 2015 5:37 AM
Free Windows Admin Tool Kit Click here and download it now
July 17th, 2015 5:32am

Is it work in Skype FB ?
  • Edited by banzalini Friday, July 17, 2015 5:37 AM
July 17th, 2015 5:32am

6500+ users across the US alone. Does not include global population.
Free Windows Admin Tool Kit Click here and download it now
August 12th, 2015 3:57pm

Here's a couple of reasons why it's important photos are displayed:

- New employees: it helps with name/face recognition when they are getting acclimated

- Receptionist: The receptionist can pull up a group conversation and see everyone's status and can quickly identify them by their picture to see if they are available or not. If the picture is hidden they have to hover over the person to see who it is. 

Can anybody confirm whether this functionality has been added in Skype for business server? I'm guessing not, but there's at least hope. 

August 13th, 2015 8:52am

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics